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();
}
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 355d552..48deb35 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -57,7 +57,6 @@
jclass WellKnownClasses::java_lang_StringFactory;
jclass WellKnownClasses::java_lang_System;
jclass WellKnownClasses::java_lang_Thread;
-jclass WellKnownClasses::java_lang_Thread__UncaughtExceptionHandler;
jclass WellKnownClasses::java_lang_ThreadGroup;
jclass WellKnownClasses::java_lang_Throwable;
jclass WellKnownClasses::java_nio_DirectByteBuffer;
@@ -121,9 +120,9 @@
jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromCodePoints;
jmethodID WellKnownClasses::java_lang_StringFactory_newStringFromStringBuilder;
jmethodID WellKnownClasses::java_lang_System_runFinalization = nullptr;
+jmethodID WellKnownClasses::java_lang_Thread_dispatchUncaughtException;
jmethodID WellKnownClasses::java_lang_Thread_init;
jmethodID WellKnownClasses::java_lang_Thread_run;
-jmethodID WellKnownClasses::java_lang_Thread__UncaughtExceptionHandler_uncaughtException;
jmethodID WellKnownClasses::java_lang_ThreadGroup_removeThread;
jmethodID WellKnownClasses::java_nio_DirectByteBuffer_init;
jmethodID WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation;
@@ -141,7 +140,6 @@
jfieldID WellKnownClasses::java_lang_Thread_lock;
jfieldID WellKnownClasses::java_lang_Thread_name;
jfieldID WellKnownClasses::java_lang_Thread_priority;
-jfieldID WellKnownClasses::java_lang_Thread_uncaughtHandler;
jfieldID WellKnownClasses::java_lang_Thread_nativePeer;
jfieldID WellKnownClasses::java_lang_ThreadGroup_groups;
jfieldID WellKnownClasses::java_lang_ThreadGroup_ngroups;
@@ -245,8 +243,6 @@
java_lang_StringFactory = CacheClass(env, "java/lang/StringFactory");
java_lang_System = CacheClass(env, "java/lang/System");
java_lang_Thread = CacheClass(env, "java/lang/Thread");
- java_lang_Thread__UncaughtExceptionHandler = CacheClass(env,
- "java/lang/Thread$UncaughtExceptionHandler");
java_lang_ThreadGroup = CacheClass(env, "java/lang/ThreadGroup");
java_lang_Throwable = CacheClass(env, "java/lang/Throwable");
java_nio_DirectByteBuffer = CacheClass(env, "java/nio/DirectByteBuffer");
@@ -273,9 +269,9 @@
java_lang_ref_ReferenceQueue_add = CacheMethod(env, java_lang_ref_ReferenceQueue.get(), true, "add", "(Ljava/lang/ref/Reference;)V");
java_lang_reflect_Proxy_invoke = CacheMethod(env, java_lang_reflect_Proxy, true, "invoke", "(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
+ java_lang_Thread_dispatchUncaughtException = CacheMethod(env, java_lang_Thread, false, "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
java_lang_Thread_init = CacheMethod(env, java_lang_Thread, false, "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
java_lang_Thread_run = CacheMethod(env, java_lang_Thread, false, "run", "()V");
- java_lang_Thread__UncaughtExceptionHandler_uncaughtException = CacheMethod(env, java_lang_Thread__UncaughtExceptionHandler, false, "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
java_lang_ThreadGroup_removeThread = CacheMethod(env, java_lang_ThreadGroup, false, "threadTerminated", "(Ljava/lang/Thread;)V");
java_nio_DirectByteBuffer_init = CacheMethod(env, java_nio_DirectByteBuffer, false, "<init>", "(JI)V");
libcore_reflect_AnnotationFactory_createAnnotation = CacheMethod(env, libcore_reflect_AnnotationFactory, true, "createAnnotation", "(Ljava/lang/Class;[Llibcore/reflect/AnnotationMember;)Ljava/lang/annotation/Annotation;");
@@ -349,7 +345,6 @@
java_lang_Thread_lock = CacheField(env, java_lang_Thread, false, "lock", "Ljava/lang/Object;");
java_lang_Thread_name = CacheField(env, java_lang_Thread, false, "name", "Ljava/lang/String;");
java_lang_Thread_priority = CacheField(env, java_lang_Thread, false, "priority", "I");
- java_lang_Thread_uncaughtHandler = CacheField(env, java_lang_Thread, false, "uncaughtExceptionHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
java_lang_Thread_nativePeer = CacheField(env, java_lang_Thread, false, "nativePeer", "J");
java_lang_ThreadGroup_groups = CacheField(env, java_lang_ThreadGroup, false, "groups", "[Ljava/lang/ThreadGroup;");
java_lang_ThreadGroup_ngroups = CacheField(env, java_lang_ThreadGroup, false, "ngroups", "I");
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index cc60b4d..c9faf69 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -69,7 +69,6 @@
static jclass java_lang_System;
static jclass java_lang_Thread;
static jclass java_lang_ThreadGroup;
- static jclass java_lang_Thread__UncaughtExceptionHandler;
static jclass java_lang_Throwable;
static jclass java_util_ArrayList;
static jclass java_util_Collections;
@@ -132,9 +131,9 @@
static jmethodID java_lang_StringFactory_newStringFromCodePoints;
static jmethodID java_lang_StringFactory_newStringFromStringBuilder;
static jmethodID java_lang_System_runFinalization;
+ static jmethodID java_lang_Thread_dispatchUncaughtException;
static jmethodID java_lang_Thread_init;
static jmethodID java_lang_Thread_run;
- static jmethodID java_lang_Thread__UncaughtExceptionHandler_uncaughtException;
static jmethodID java_lang_ThreadGroup_removeThread;
static jmethodID java_nio_DirectByteBuffer_init;
static jmethodID libcore_reflect_AnnotationFactory_createAnnotation;
@@ -154,7 +153,6 @@
static jfieldID java_lang_Thread_lock;
static jfieldID java_lang_Thread_name;
static jfieldID java_lang_Thread_priority;
- static jfieldID java_lang_Thread_uncaughtHandler;
static jfieldID java_lang_Thread_nativePeer;
static jfieldID java_lang_ThreadGroup_groups;
static jfieldID java_lang_ThreadGroup_ngroups;