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_test.cc b/runtime/instrumentation_test.cc
index 7390f4f..9b77d12 100644
--- a/runtime/instrumentation_test.cc
+++ b/runtime/instrumentation_test.cc
@@ -48,6 +48,7 @@
       received_field_written_event(false),
       received_field_written_object_event(false),
       received_exception_thrown_event(false),
+      received_exception_handled_event(false),
       received_branch_event(false),
       received_invoke_virtual_or_interface_event(false),
       received_watched_frame_pop(false) {}
@@ -131,6 +132,12 @@
     received_exception_thrown_event = true;
   }
 
+  void ExceptionHandled(Thread* self ATTRIBUTE_UNUSED,
+                        Handle<mirror::Throwable> throwable ATTRIBUTE_UNUSED)
+      OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
+    received_exception_handled_event = true;
+  }
+
   void Branch(Thread* thread ATTRIBUTE_UNUSED,
               ArtMethod* method ATTRIBUTE_UNUSED,
               uint32_t dex_pc ATTRIBUTE_UNUSED,
@@ -163,6 +170,7 @@
     received_field_written_event = false;
     received_field_written_object_event = false;
     received_exception_thrown_event = false;
+    received_exception_handled_event = false;
     received_branch_event = false;
     received_invoke_virtual_or_interface_event = false;
     received_watched_frame_pop = false;
@@ -177,6 +185,7 @@
   bool received_field_written_event;
   bool received_field_written_object_event;
   bool received_exception_thrown_event;
+  bool received_exception_handled_event;
   bool received_branch_event;
   bool received_invoke_virtual_or_interface_event;
   bool received_watched_frame_pop;
@@ -369,6 +378,8 @@
         return instr->HasFieldWriteListeners();
       case instrumentation::Instrumentation::kExceptionThrown:
         return instr->HasExceptionThrownListeners();
+      case instrumentation::Instrumentation::kExceptionHandled:
+        return instr->HasExceptionHandledListeners();
       case instrumentation::Instrumentation::kBranch:
         return instr->HasBranchListeners();
       case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
@@ -429,6 +440,13 @@
       case instrumentation::Instrumentation::kWatchedFramePop:
         instr->WatchedFramePopped(self, frame);
         break;
+      case instrumentation::Instrumentation::kExceptionHandled: {
+        ThrowArithmeticExceptionDivideByZero();
+        mirror::Throwable* event_exception = self->GetException();
+        self->ClearException();
+        instr->ExceptionHandledEvent(self, event_exception);
+        break;
+      }
       default:
         LOG(FATAL) << "Unknown instrumentation event " << event_type;
         UNREACHABLE();
@@ -455,6 +473,8 @@
             (with_object && listener.received_field_written_object_event);
       case instrumentation::Instrumentation::kExceptionThrown:
         return listener.received_exception_thrown_event;
+      case instrumentation::Instrumentation::kExceptionHandled:
+        return listener.received_exception_handled_event;
       case instrumentation::Instrumentation::kBranch:
         return listener.received_branch_event;
       case instrumentation::Instrumentation::kInvokeVirtualOrInterface:
@@ -484,6 +504,7 @@
   // Check there is no registered listener.
   EXPECT_FALSE(instr->HasDexPcListeners());
   EXPECT_FALSE(instr->HasExceptionThrownListeners());
+  EXPECT_FALSE(instr->HasExceptionHandledListeners());
   EXPECT_FALSE(instr->HasFieldReadListeners());
   EXPECT_FALSE(instr->HasFieldWriteListeners());
   EXPECT_FALSE(instr->HasMethodEntryListeners());
@@ -587,6 +608,10 @@
             /*with_object*/ false);
 }
 
+TEST_F(InstrumentationTest, ExceptionHandledEvent) {
+  TestEvent(instrumentation::Instrumentation::kExceptionHandled);
+}
+
 TEST_F(InstrumentationTest, ExceptionThrownEvent) {
   TestEvent(instrumentation::Instrumentation::kExceptionThrown);
 }