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,