Use Thread.dispatchUncaughtException() rather than duplicating logic.

Previously, the runtime duplicated the logic in Thread's methods
dispatchUncaughtException() and getUncaughtExceptionHandler().
Since we're modifying this logic to ensure that uncaught
exceptions are logged, this CL changes the runtime to call
dispatchUncaughtException instead. This also has the benefit
that we can remove Thread.UncaughtExceptionHandler from the
list of well known classes.

Test: art/tools/run-libcore-tests.sh --mode=host --variant=X32
Bug: 29624607
Change-Id: Id7161d841d64ff9d8f2a7ec1c8c0c5c911ff0b64
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 76f3161..1782867 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1817,22 +1817,12 @@
   ScopedLocalRef<jthrowable> exception(tlsPtr_.jni_env, tlsPtr_.jni_env->ExceptionOccurred());
   tlsPtr_.jni_env->ExceptionClear();
 
-  // If the thread has its own handler, use that.
-  ScopedLocalRef<jobject> handler(tlsPtr_.jni_env,
-                                  tlsPtr_.jni_env->GetObjectField(peer.get(),
-                                      WellKnownClasses::java_lang_Thread_uncaughtHandler));
-  if (handler.get() == nullptr) {
-    // Otherwise use the thread group's default handler.
-    handler.reset(tlsPtr_.jni_env->GetObjectField(peer.get(),
-                                                  WellKnownClasses::java_lang_Thread_group));
-  }
+  // Call the Thread instance's dispatchUncaughtException(Throwable)
+  tlsPtr_.jni_env->CallVoidMethod(peer.get(),
+      WellKnownClasses::java_lang_Thread_dispatchUncaughtException,
+      exception.get());
 
-  // Call the handler.
-  tlsPtr_.jni_env->CallVoidMethod(handler.get(),
-      WellKnownClasses::java_lang_Thread__UncaughtExceptionHandler_uncaughtException,
-      peer.get(), exception.get());
-
-  // If the handler threw, clear that exception too.
+  // If the dispatchUncaughtException threw, clear that exception too.
   tlsPtr_.jni_env->ExceptionClear();
 }