diff options
Diffstat (limited to 'runtime/instrumentation.cc')
| -rw-r--r-- | runtime/instrumentation.cc | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index b3528d8d42..4d8c6872e8 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -110,6 +110,7 @@ Instrumentation::Instrumentation() have_watched_frame_pop_listeners_(false), have_branch_listeners_(false), have_invoke_virtual_or_interface_listeners_(false), + have_exception_handled_listeners_(false), deoptimized_methods_lock_("deoptimized methods lock", kDeoptimizedMethodsLock), deoptimization_enabled_(false), interpreter_handler_table_(kMainHandlerTable), @@ -513,6 +514,11 @@ void Instrumentation::AddListener(InstrumentationListener* listener, uint32_t ev watched_frame_pop_listeners_, listener, &have_watched_frame_pop_listeners_); + PotentiallyAddListenerTo(kExceptionHandled, + events, + exception_handled_listeners_, + listener, + &have_exception_handled_listeners_); UpdateInterpreterHandlerTable(); } @@ -595,6 +601,11 @@ void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t watched_frame_pop_listeners_, listener, &have_watched_frame_pop_listeners_); + PotentiallyRemoveListenerFrom(kExceptionHandled, + events, + exception_handled_listeners_, + listener, + &have_exception_handled_listeners_); UpdateInterpreterHandlerTable(); } @@ -1118,10 +1129,28 @@ void Instrumentation::ExceptionThrownEvent(Thread* thread, listener->ExceptionThrown(thread, h_exception); } } + // See b/65049545 for discussion about this behavior. + thread->AssertNoPendingException(); thread->SetException(h_exception.Get()); } } +void Instrumentation::ExceptionHandledEvent(Thread* thread, + mirror::Throwable* exception_object) const { + Thread* self = Thread::Current(); + StackHandleScope<1> hs(self); + Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object)); + if (HasExceptionHandledListeners()) { + // We should have cleared the exception so that callers can detect a new one. + DCHECK(thread->GetException() == nullptr); + for (InstrumentationListener* listener : exception_handled_listeners_) { + if (listener != nullptr) { + listener->ExceptionHandled(thread, h_exception); + } + } + } +} + // Computes a frame ID by ignoring inlined frames. size_t Instrumentation::ComputeFrameId(Thread* self, size_t frame_depth, |