8005817: Shark: implement deoptimization support
Reviewed-by: twisti
Contributed-by: Roman Kennke <rkennke@redhat.com>
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Fri Jan 11 16:47:23 2013 -0800
@@ -98,10 +98,20 @@
#endif // CC_INTERP
void frame::patch_pc(Thread* thread, address pc) {
- // We borrow this call to set the thread pointer in the interpreter
- // state; the hook to set up deoptimized frames isn't supplied it.
- assert(pc == NULL, "should be");
- get_interpreterState()->set_thread((JavaThread *) thread);
+
+ 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
+ // state; the hook to set up deoptimized frames isn't supplied it.
+ assert(pc == NULL, "should be");
+ get_interpreterState()->set_thread((JavaThread *) thread);
+ }
}
bool frame::safe_for_sender(JavaThread *thread) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Fri Jan 11 16:47:23 2013 -0800
@@ -45,27 +45,36 @@
case ZeroFrame::ENTRY_FRAME:
_pc = StubRoutines::call_stub_return_pc();
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
case ZeroFrame::INTERPRETER_FRAME:
_pc = NULL;
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
- case ZeroFrame::SHARK_FRAME:
+ case ZeroFrame::SHARK_FRAME: {
_pc = zero_sharkframe()->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;
-
+ }
case ZeroFrame::FAKE_STUB_FRAME:
_pc = NULL;
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
default:
ShouldNotReachHere();
}
- _deopt_state = not_deoptimized;
}
// Accessors
--- a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Fri Jan 11 16:47:23 2013 -0800
@@ -68,6 +68,10 @@
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 {
return (intptr_t *) value_of_word(unextended_sp_off);
}
--- a/hotspot/src/share/vm/shark/sharkInvariants.hpp Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp Fri Jan 11 16:47:23 2013 -0800
@@ -99,12 +99,14 @@
DebugInformationRecorder* debug_info() const {
return env()->debug_info();
}
+ SharkCodeBuffer* code_buffer() const {
+ return builder()->code_buffer();
+ }
+
+ public:
Dependencies* dependencies() const {
return env()->dependencies();
}
- SharkCodeBuffer* code_buffer() const {
- return builder()->code_buffer();
- }
// Commonly used classes
protected:
--- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Fri Jan 11 16:47:23 2013 -0800
@@ -1030,7 +1030,6 @@
dest_method->holder() == java_lang_Object_klass())
return dest_method;
-#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
// 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
// implements this method. This makes the compiled code dependent
@@ -1064,6 +1063,8 @@
if (monomorphic_target != NULL) {
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
// understand. It's to inhibit casting in one direction,
// possibly because objects in Opto can have inexact
@@ -1097,7 +1098,6 @@
// with non-monomorphic targets if the receiver has an exact
// type. We don't mark types this way, so we can't do this.
-#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
return NULL;
}
@@ -1298,8 +1298,9 @@
// Try to inline the call
if (!call_is_virtual) {
- if (SharkInliner::attempt_inline(call_method, current_state()))
+ if (SharkInliner::attempt_inline(call_method, current_state())) {
return;
+ }
}
// Find the method we are calling