diff options
author | 2022-05-13 21:22:28 +0000 | |
---|---|---|
committer | 2022-05-24 08:57:02 +0000 | |
commit | 9fc3505d59c0c0b206de313add209799b6251881 (patch) | |
tree | 699b4ba206d6a19a6845ba993cc83be4ba6a2ffc /runtime/quick_exception_handler.cc | |
parent | 771d1988bb2fa88f86861af3456370e2555819d1 (diff) |
Update implementation of method unwind callbacks
Earlier method unwind callbacks for quick / native methods was based on
the instrumentation stack entries. JITed code no longer have entries in
instrumentation stack and native code also will soon not use
instrumentation stack. So update the implementation to record the
methods on the stack as we walk them for finding the catch block and use
them to call the method unwind callbacks when necessary.
Bug: 206029744
Test: art/test.py
Change-Id: I9a5f6e544cadc78e1e93d8b2f4e5ec58b04d6ea3
Diffstat (limited to 'runtime/quick_exception_handler.cc')
-rw-r--r-- | runtime/quick_exception_handler.cc | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 2a6929a523..f8bfb5a0ad 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -16,6 +16,7 @@ #include "quick_exception_handler.h" #include <ios> +#include <queue> #include "arch/context.h" #include "art_method-inl.h" @@ -95,7 +96,19 @@ class CatchBlockStackVisitor final : public StackVisitor { DCHECK(method->IsCalleeSaveMethod()); return true; } - return HandleTryItems(method); + bool continue_stack_walk = HandleTryItems(method); + // Collect methods for which MethodUnwind callback needs to be invoked. MethodUnwind callback + // can potentially throw, so we want to call these after we find the catch block. + // We stop the stack walk when we find the catch block. If we are ending the stack walk we don't + // have to unwind this method so don't record it. + if (continue_stack_walk) { + unwound_methods_.push(method); + } + return continue_stack_walk; + } + + std::queue<ArtMethod*>& GetUnwoundMethods() { + return unwound_methods_; } private: @@ -139,6 +152,9 @@ class CatchBlockStackVisitor final : public StackVisitor { QuickExceptionHandler* const exception_handler_; // The number of frames to skip searching for catches in. uint32_t skip_frames_; + // The list of methods we would skip to reach the catch block. We record these to call + // MethodUnwind callbacks. + std::queue<ArtMethod*> unwound_methods_; DISALLOW_COPY_AND_ASSIGN(CatchBlockStackVisitor); }; @@ -147,7 +163,7 @@ class CatchBlockStackVisitor final : public StackVisitor { // Note that this might change the exception being thrown. void QuickExceptionHandler::FindCatch(ObjPtr<mirror::Throwable> exception) { DCHECK(!is_deoptimization_); - instrumentation::InstrumentationStackPopper popper(self_); + instrumentation::Instrumentation* instr = Runtime::Current()->GetInstrumentation(); // The number of total frames we have so far popped. uint32_t already_popped = 0; bool popped_to_top = true; @@ -195,9 +211,13 @@ void QuickExceptionHandler::FindCatch(ObjPtr<mirror::Throwable> exception) { handler_method_header_->IsOptimized()) { SetCatchEnvironmentForOptimizedHandler(&visitor); } - popped_to_top = - popper.PopFramesTo(reinterpret_cast<uintptr_t>(handler_quick_frame_), exception_ref); + popped_to_top = instr->ProcessMethodUnwindCallbacks(self_, + visitor.GetUnwoundMethods(), + exception_ref); } while (!popped_to_top); + + // Pop off frames on instrumentation stack to keep it in sync with what is on the stack. + instr->PopInstrumentationStackUntil(self_, reinterpret_cast<uintptr_t>(handler_quick_frame_)); if (!clear_exception_) { // Put exception back in root set with clear throw location. self_->SetException(exception_ref.Get()); @@ -642,7 +662,7 @@ uintptr_t QuickExceptionHandler::UpdateInstrumentationStack() { uintptr_t return_pc = 0; if (method_tracing_active_) { instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); - return_pc = instrumentation->PopFramesForDeoptimization( + return_pc = instrumentation->PopInstrumentationStackUntil( self_, reinterpret_cast<uintptr_t>(handler_quick_frame_)); } return return_pc; |