diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index df05521d05096fec2fb75b95e9d084be294fc1bf..c8b3a7d83a682f35007534c0b8b4afcda791b140 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -107,7 +107,6 @@ static void deopt_caller() { RegisterMap reg_map(thread, false); frame runtime_frame = thread->last_frame(); frame caller_frame = runtime_frame.sender(®_map); - // bypass VM_DeoptimizeFrame and deoptimize the frame directly Deoptimization::deoptimize_frame(thread, caller_frame.id()); assert(caller_is_deopted(), "Must be deoptimized"); } @@ -368,8 +367,7 @@ JRT_BLOCK_ENTRY(address, Runtime1::counter_overflow(JavaThread* thread, int bci, if (osr_nm != NULL) { RegisterMap map(thread, false); frame fr = thread->last_frame().sender(&map); - VM_DeoptimizeFrame deopt(thread, fr.id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(thread, fr.id()); } JRT_BLOCK_END return NULL; @@ -441,8 +439,8 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t // We don't really want to deoptimize the nmethod itself since we // can actually continue in the exception handler ourselves but I // don't see an easy way to have the desired effect. - VM_DeoptimizeFrame deopt(thread, caller_frame.id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); + assert(caller_is_deopted(), "Must be deoptimized"); return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); } @@ -835,8 +833,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i nm->make_not_entrant(); } - VM_DeoptimizeFrame deopt(thread, caller_frame.id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); // Return to the now deoptimized frame. } diff --git a/src/share/vm/includeDB_features b/src/share/vm/includeDB_features index 39e1149b06f97c67d9a9a81678fd375d6c5c4dae..401a67a941a03bf5fb47d8a2374dcae9fe119c76 100644 --- a/src/share/vm/includeDB_features +++ b/src/share/vm/includeDB_features @@ -154,6 +154,7 @@ jvmtiExtensions.hpp allocation.hpp jvmtiExtensions.hpp jvmti.h jvmtiExtensions.hpp jvmtiEnv.hpp +jvmtiImpl.cpp deoptimization.hpp jvmtiImpl.cpp exceptions.hpp jvmtiImpl.cpp handles.hpp jvmtiImpl.cpp handles.inline.hpp diff --git a/src/share/vm/includeDB_jvmti b/src/share/vm/includeDB_jvmti index 704cf78afefc9cd6c278c820e54d83a79faad024..76a1128c5f4bf2f0df310cee09b54d736c4be3cd 100644 --- a/src/share/vm/includeDB_jvmti +++ b/src/share/vm/includeDB_jvmti @@ -87,6 +87,7 @@ jvmtiEnv.cpp vmThread.hpp jvmtiEnv.hpp jvmtiEnvBase.hpp jvmtiEnvBase.cpp biasedLocking.hpp +jvmtiEnvBase.cpp deoptimization.hpp jvmtiEnvBase.cpp interfaceSupport.hpp jvmtiEnvBase.cpp jfieldIDWorkaround.hpp jvmtiEnvBase.cpp jvmtiEnv.hpp diff --git a/src/share/vm/prims/jvmtiEnv.cpp b/src/share/vm/prims/jvmtiEnv.cpp index bc2c20e409ba7f52953410c47152bfcf7f93dd9e..3c34771335c9b5902d63e8d9439410457722ecce 100644 --- a/src/share/vm/prims/jvmtiEnv.cpp +++ b/src/share/vm/prims/jvmtiEnv.cpp @@ -1407,8 +1407,7 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) { // If any of the top 2 frames is a compiled one, need to deoptimize it for (int i = 0; i < 2; i++) { if (!is_interpreted[i]) { - VM_DeoptimizeFrame op(java_thread, frame_sp[i]); - VMThread::execute(&op); + Deoptimization::deoptimize_frame(java_thread, frame_sp[i]); } } diff --git a/src/share/vm/prims/jvmtiEnvBase.cpp b/src/share/vm/prims/jvmtiEnvBase.cpp index 044b79fa258aa51681e7eee0e3114f3512720047..53af49971b8c4f452b3bccdc63eb7b6a4131cb07 100644 --- a/src/share/vm/prims/jvmtiEnvBase.cpp +++ b/src/share/vm/prims/jvmtiEnvBase.cpp @@ -1322,8 +1322,7 @@ JvmtiEnvBase::check_top_frame(JavaThread* current_thread, JavaThread* java_threa if (!vf->fr().can_be_deoptimized()) { return JVMTI_ERROR_OPAQUE_FRAME; } - VM_DeoptimizeFrame deopt(java_thread, jvf->fr().id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(java_thread, jvf->fr().id()); } // Get information about method return type diff --git a/src/share/vm/prims/jvmtiImpl.cpp b/src/share/vm/prims/jvmtiImpl.cpp index 0fb385d1e7f704267fef58a41eb1bbbca8dd2401..7f08baae18db918526a5fd871ea0a56123c139b8 100644 --- a/src/share/vm/prims/jvmtiImpl.cpp +++ b/src/share/vm/prims/jvmtiImpl.cpp @@ -799,8 +799,7 @@ void VM_GetOrSetLocal::doit() { // Schedule deoptimization so that eventually the local // update will be written to an interpreter frame. - VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id()); // Now store a new value for the local which will be applied // once deoptimization occurs. Note however that while this diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp index 4dd9e97059caa1e26bc68b0d3a2a76c965ff1fdf..e6a14d7100547b4aaf99ffc46c303fa02bea468f 100644 --- a/src/share/vm/runtime/deoptimization.cpp +++ b/src/share/vm/runtime/deoptimization.cpp @@ -1065,7 +1065,9 @@ void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) } -void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { +void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) { + assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(), + "can only deoptimize other thread at a safepoint"); // Compute frame and register map based on thread and sp. RegisterMap reg_map(thread, UseBiasedLocking); frame fr = thread->last_frame(); @@ -1076,6 +1078,16 @@ void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { } +void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { + if (thread == Thread::current()) { + Deoptimization::deoptimize_frame_internal(thread, id); + } else { + VM_DeoptimizeFrame deopt(thread, id); + VMThread::execute(&deopt); + } +} + + // JVMTI PopFrame support JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address)) { diff --git a/src/share/vm/runtime/deoptimization.hpp b/src/share/vm/runtime/deoptimization.hpp index 83bccfd3fc5e43c44dd943470efe95ce26421745..c0b8c6f396f574c41cc427bfba2fcbda630a64e3 100644 --- a/src/share/vm/runtime/deoptimization.hpp +++ b/src/share/vm/runtime/deoptimization.hpp @@ -216,6 +216,10 @@ class Deoptimization : AllStatic { // Only called from VMDeoptimizeFrame // @argument thread. Thread where stub_frame resides. // @argument id. id of frame that should be deoptimized. + static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id); + + // If thread is not the current thread then execute + // VM_DeoptimizeFrame otherwise deoptimize directly. static void deoptimize_frame(JavaThread* thread, intptr_t* id); // Statistics diff --git a/src/share/vm/runtime/safepoint.cpp b/src/share/vm/runtime/safepoint.cpp index e1a1d432ec2b68994af262c65f08797bec1c392e..b7671271cd1b8d53b646401543137a23897c83fc 100644 --- a/src/share/vm/runtime/safepoint.cpp +++ b/src/share/vm/runtime/safepoint.cpp @@ -940,8 +940,7 @@ void ThreadSafepointState::handle_polling_page_exception() { // as otherwise we may never deliver it. if (thread()->has_async_condition()) { ThreadInVMfromJavaNoAsyncException __tiv(thread()); - VM_DeoptimizeFrame deopt(thread(), caller_fr.id()); - VMThread::execute(&deopt); + Deoptimization::deoptimize_frame(thread(), caller_fr.id()); } // If an exception has been installed we must check for a pending deoptimization diff --git a/src/share/vm/runtime/vm_operations.cpp b/src/share/vm/runtime/vm_operations.cpp index d6cf352f6d77400d9e6944b2f8845aea65186e4d..f58509c66d3a21a2a779a5cea385b04f1ac26cd1 100644 --- a/src/share/vm/runtime/vm_operations.cpp +++ b/src/share/vm/runtime/vm_operations.cpp @@ -100,7 +100,7 @@ VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) { void VM_DeoptimizeFrame::doit() { - Deoptimization::deoptimize_frame(_thread, _id); + Deoptimization::deoptimize_frame_internal(_thread, _id); } diff --git a/src/share/vm/runtime/vm_operations.hpp b/src/share/vm/runtime/vm_operations.hpp index bd0bebbc777d37a7152184aae83e997e44db2c82..f6d9d052476b40b9f9617b4cda8daaece7a549c1 100644 --- a/src/share/vm/runtime/vm_operations.hpp +++ b/src/share/vm/runtime/vm_operations.hpp @@ -231,12 +231,18 @@ class VM_Deoptimize: public VM_Operation { bool allow_nested_vm_operations() const { return true; } }; + +// Deopt helper that can deoptimize frames in threads other than the +// current thread. Only used through Deoptimization::deoptimize_frame. class VM_DeoptimizeFrame: public VM_Operation { + friend class Deoptimization; + private: JavaThread* _thread; intptr_t* _id; - public: VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id); + + public: VMOp_Type type() const { return VMOp_DeoptimizeFrame; } void doit(); bool allow_nested_vm_operations() const { return true; }