Use WellKnownClasses in ThrowStackOverflowError to reduce changes of further stack overflow

Bug: 17463118

(cherry picked from commit bfc2b98a3cf7a9d580f2477e54aabded5004fd26)

Change-Id: Iea04bb7f6c4daa9cbdb8ee6ce8ddcbeb9f05aa3d
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index d834d4d..a78c2c0 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -33,8 +33,10 @@
 
 namespace art {
 
-static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, mirror::ArtMethod* referrer,
-                                                      int32_t component_count, Thread* self,
+static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx,
+                                                      mirror::ArtMethod* referrer,
+                                                      int32_t component_count,
+                                                      Thread* self,
                                                       bool access_check)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   if (UNLIKELY(component_count < 0)) {
@@ -56,9 +58,10 @@
     } else {
       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
       DCHECK(throw_location.GetMethod() == referrer);
-      self->ThrowNewExceptionF(throw_location, "Ljava/lang/InternalError;",
-                               "Found type %s; filled-new-array not implemented for anything but 'int'",
-                               PrettyDescriptor(klass).c_str());
+      self->ThrowNewExceptionF(
+          throw_location, "Ljava/lang/InternalError;",
+          "Found type %s; filled-new-array not implemented for anything but 'int'",
+          PrettyDescriptor(klass).c_str());
     }
     return nullptr;  // Failure
   }
@@ -92,8 +95,10 @@
 }
 
 // Helper function to allocate array for FILLED_NEW_ARRAY.
-mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx, mirror::ArtMethod* referrer,
-                                                      int32_t component_count, Thread* self,
+mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx,
+                                                      mirror::ArtMethod* referrer,
+                                                      int32_t component_count,
+                                                      Thread* self,
                                                       bool access_check,
                                                       gc::AllocatorType /* allocator_type */) {
   mirror::Class* klass = CheckFilledNewArrayAlloc(type_idx, referrer, component_count, self,
@@ -144,24 +149,19 @@
     // TODO: Use String::FromModifiedUTF...?
     ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg.c_str()));
     if (s.get() != nullptr) {
-      jfieldID detail_message_id = env->GetFieldID(WellKnownClasses::java_lang_Throwable,
-                                                   "detailMessage", "Ljava/lang/String;");
-      env->SetObjectField(exc.get(), detail_message_id, s.get());
+      env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_detailMessage, s.get());
 
       // cause.
-      jfieldID cause_id = env->GetFieldID(WellKnownClasses::java_lang_Throwable,
-                                          "cause", "Ljava/lang/Throwable;");
-      env->SetObjectField(exc.get(), cause_id, exc.get());
+      env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_cause, exc.get());
 
       // suppressedExceptions.
-      jfieldID emptylist_id = env->GetStaticFieldID(WellKnownClasses::java_util_Collections,
-                                                    "EMPTY_LIST", "Ljava/util/List;");
       ScopedLocalRef<jobject> emptylist(env, env->GetStaticObjectField(
-              WellKnownClasses::java_util_Collections, emptylist_id));
+          WellKnownClasses::java_util_Collections,
+          WellKnownClasses::java_util_Collections_EMPTY_LIST));
       CHECK(emptylist.get() != nullptr);
-      jfieldID suppressed_id = env->GetFieldID(WellKnownClasses::java_lang_Throwable,
-                                               "suppressedExceptions", "Ljava/util/List;");
-      env->SetObjectField(exc.get(), suppressed_id, emptylist.get());
+      env->SetObjectField(exc.get(),
+                          WellKnownClasses::java_lang_Throwable_suppressedExceptions,
+                          emptylist.get());
 
       // stackState is set as result of fillInStackTrace. fillInStackTrace calls
       // nativeFillInStackTrace.
@@ -171,19 +171,17 @@
         stack_state_val.reset(soa.Self()->CreateInternalStackTrace<false>(soa));
       }
       if (stack_state_val.get() != nullptr) {
-        jfieldID stackstateID = env->GetFieldID(WellKnownClasses::java_lang_Throwable,
-            "stackState", "Ljava/lang/Object;");
-        env->SetObjectField(exc.get(), stackstateID, stack_state_val.get());
+        env->SetObjectField(exc.get(),
+                            WellKnownClasses::java_lang_Throwable_stackState,
+                            stack_state_val.get());
 
         // stackTrace.
-        jfieldID stack_trace_elem_id = env->GetStaticFieldID(
-            WellKnownClasses::libcore_util_EmptyArray, "STACK_TRACE_ELEMENT",
-            "[Ljava/lang/StackTraceElement;");
         ScopedLocalRef<jobject> stack_trace_elem(env, env->GetStaticObjectField(
-                WellKnownClasses::libcore_util_EmptyArray, stack_trace_elem_id));
-        jfieldID stacktrace_id = env->GetFieldID(
-            WellKnownClasses::java_lang_Throwable, "stackTrace", "[Ljava/lang/StackTraceElement;");
-        env->SetObjectField(exc.get(), stacktrace_id, stack_trace_elem.get());
+            WellKnownClasses::libcore_util_EmptyArray,
+            WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT));
+        env->SetObjectField(exc.get(),
+                            WellKnownClasses::java_lang_Throwable_stackTrace,
+                            stack_trace_elem.get());
 
         // Throw the exception.
         ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -326,7 +324,8 @@
         }
       }
       CHECK_NE(throws_index, -1);
-      mirror::ObjectArray<mirror::Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
+      mirror::ObjectArray<mirror::Class>* declared_exceptions =
+          proxy_class->GetThrows()->Get(throws_index);
       mirror::Class* exception_class = exception->GetClass();
       bool declares_exception = false;
       for (int i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) {
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 7068a4d..f66e11a 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -97,11 +97,18 @@
 jfieldID WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup;
 jfieldID WellKnownClasses::java_lang_ThreadGroup_name;
 jfieldID WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup;
+jfieldID WellKnownClasses::java_lang_Throwable_cause;
+jfieldID WellKnownClasses::java_lang_Throwable_detailMessage;
+jfieldID WellKnownClasses::java_lang_Throwable_stackTrace;
+jfieldID WellKnownClasses::java_lang_Throwable_stackState;
+jfieldID WellKnownClasses::java_lang_Throwable_suppressedExceptions;
 jfieldID WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod;
 jfieldID WellKnownClasses::java_lang_reflect_Field_artField;
 jfieldID WellKnownClasses::java_lang_reflect_Proxy_h;
 jfieldID WellKnownClasses::java_nio_DirectByteBuffer_capacity;
 jfieldID WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress;
+jfieldID WellKnownClasses::java_util_Collections_EMPTY_LIST;
+jfieldID WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT;
 jfieldID WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_data;
 jfieldID WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_length;
 jfieldID WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_offset;
@@ -205,12 +212,19 @@
   java_lang_ThreadGroup_mainThreadGroup = CacheField(env, java_lang_ThreadGroup, true, "mainThreadGroup", "Ljava/lang/ThreadGroup;");
   java_lang_ThreadGroup_name = CacheField(env, java_lang_ThreadGroup, false, "name", "Ljava/lang/String;");
   java_lang_ThreadGroup_systemThreadGroup = CacheField(env, java_lang_ThreadGroup, true, "systemThreadGroup", "Ljava/lang/ThreadGroup;");
+  java_lang_Throwable_cause = CacheField(env, java_lang_Throwable, false, "cause", "Ljava/lang/Throwable;");
+  java_lang_Throwable_detailMessage = CacheField(env, java_lang_Throwable, false, "detailMessage", "Ljava/lang/String;");
+  java_lang_Throwable_stackTrace = CacheField(env, java_lang_Throwable, false, "stackTrace", "[Ljava/lang/StackTraceElement;");
+  java_lang_Throwable_stackState = CacheField(env, java_lang_Throwable, false, "stackState", "Ljava/lang/Object;");
+  java_lang_Throwable_suppressedExceptions = CacheField(env, java_lang_Throwable, false, "suppressedExceptions", "Ljava/util/List;");
   java_lang_reflect_AbstractMethod_artMethod = CacheField(env, java_lang_reflect_AbstractMethod, false, "artMethod", "Ljava/lang/reflect/ArtMethod;");
   java_lang_reflect_Field_artField = CacheField(env, java_lang_reflect_Field, false, "artField", "Ljava/lang/reflect/ArtField;");
   java_lang_reflect_Proxy_h = CacheField(env, java_lang_reflect_Proxy, false, "h", "Ljava/lang/reflect/InvocationHandler;");
   java_nio_DirectByteBuffer_capacity = CacheField(env, java_nio_DirectByteBuffer, false, "capacity", "I");
   java_nio_DirectByteBuffer_effectiveDirectAddress = CacheField(env, java_nio_DirectByteBuffer, false, "effectiveDirectAddress", "J");
-  org_apache_harmony_dalvik_ddmc_Chunk_data = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "data", "[B");
+  java_nio_DirectByteBuffer_effectiveDirectAddress = CacheField(env, java_nio_DirectByteBuffer, false, "effectiveDirectAddress", "J");
+  java_util_Collections_EMPTY_LIST = CacheField(env, java_util_Collections, true, "EMPTY_LIST", "Ljava/util/List;");
+  libcore_util_EmptyArray_STACK_TRACE_ELEMENT = CacheField(env, libcore_util_EmptyArray, true, "STACK_TRACE_ELEMENT", "[Ljava/lang/StackTraceElement;");
   org_apache_harmony_dalvik_ddmc_Chunk_length = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "length", "I");
   org_apache_harmony_dalvik_ddmc_Chunk_offset = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "offset", "I");
   org_apache_harmony_dalvik_ddmc_Chunk_type = CacheField(env, org_apache_harmony_dalvik_ddmc_Chunk, false, "type", "I");
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index b10106c..3780733 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -114,8 +114,15 @@
   static jfieldID java_lang_ThreadGroup_mainThreadGroup;
   static jfieldID java_lang_ThreadGroup_name;
   static jfieldID java_lang_ThreadGroup_systemThreadGroup;
+  static jfieldID java_lang_Throwable_cause;
+  static jfieldID java_lang_Throwable_detailMessage;
+  static jfieldID java_lang_Throwable_stackTrace;
+  static jfieldID java_lang_Throwable_stackState;
+  static jfieldID java_lang_Throwable_suppressedExceptions;
   static jfieldID java_nio_DirectByteBuffer_capacity;
   static jfieldID java_nio_DirectByteBuffer_effectiveDirectAddress;
+  static jfieldID java_util_Collections_EMPTY_LIST;
+  static jfieldID libcore_util_EmptyArray_STACK_TRACE_ELEMENT;
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_data;
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_length;
   static jfieldID org_apache_harmony_dalvik_ddmc_Chunk_offset;