From 86125c3ee171d839b451057234a474084fc77cf8 Mon Sep 17 00:00:00 2001 From: never Date: Tue, 19 Oct 2010 16:14:34 -0700 Subject: [PATCH] 6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places Reviewed-by: kvn, twisti --- src/share/vm/c1/c1_Runtime1.cpp | 11 ++++------- src/share/vm/includeDB_features | 1 + src/share/vm/includeDB_jvmti | 1 + src/share/vm/prims/jvmtiEnv.cpp | 3 +-- src/share/vm/prims/jvmtiEnvBase.cpp | 3 +-- src/share/vm/prims/jvmtiImpl.cpp | 3 +-- src/share/vm/runtime/deoptimization.cpp | 14 +++++++++++++- src/share/vm/runtime/deoptimization.hpp | 4 ++++ src/share/vm/runtime/safepoint.cpp | 3 +-- src/share/vm/runtime/vm_operations.cpp | 2 +- src/share/vm/runtime/vm_operations.hpp | 8 +++++++- 11 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index df05521d0..c8b3a7d83 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 39e1149b0..401a67a94 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 704cf78af..76a1128c5 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 bc2c20e40..3c3477133 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 044b79fa2..53af49971 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 0fb385d1e..7f08baae1 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 4dd9e9705..e6a14d710 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 83bccfd3f..c0b8c6f39 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 e1a1d432e..b7671271c 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 d6cf352f6..f58509c66 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 bd0bebbc7..f6d9d0524 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; } -- GitLab