Revert "Revert "JVMTI Exception and ExceptionCatch events""
Fixed error where we were incorrectly not updating a ShadowFrame
dex_pc causing deoptimization errors.
Bug: 62821960
Bug: 65049545
Test: ./test.py --host -j50
Test: ./art/tools/run-libcore-tests.sh \
--mode=host --variant-X32 --debug
This reverts commit 959742483885779f106e000df6dd422fc8657931.
Change-Id: I91ab2bc3e645ddf0359c189b19a59a3ecf0d8921
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 05384b4..6e457a4 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -108,6 +108,7 @@
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),
@@ -510,6 +511,11 @@
watched_frame_pop_listeners_,
listener,
&have_watched_frame_pop_listeners_);
+ PotentiallyAddListenerTo(kExceptionHandled,
+ events,
+ exception_handled_listeners_,
+ listener,
+ &have_exception_handled_listeners_);
UpdateInterpreterHandlerTable();
}
@@ -592,6 +598,11 @@
watched_frame_pop_listeners_,
listener,
&have_watched_frame_pop_listeners_);
+ PotentiallyRemoveListenerFrom(kExceptionHandled,
+ events,
+ exception_handled_listeners_,
+ listener,
+ &have_exception_handled_listeners_);
UpdateInterpreterHandlerTable();
}
@@ -1114,10 +1125,28 @@
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,