Use specific exception class to abort transaction

We used to throw a java.lang.InternalError when aborting a
transaction (when preinitializing image classes at compilation time).

We now use dedicated class dalvik.system.TransactionAbortError that
is only thrown by the compiler to abort a transaction. This class has
constructors taking a java.lang.Throwable "cause" so we can wrap
exceptions causing the transaction to abort (for instance class
java.lang.ClassNotFoundException) and give more information about the
cause of the transaction abort.

Bug: 20019689
Change-Id: I019a72a1c754d8bba6a7ad6bb0f02e4fd6668622
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 281f332..2aa4af4 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -37,6 +37,7 @@
 #include "mirror/string-inl.h"
 #include "nth_caller_visitor.h"
 #include "thread.h"
+#include "transaction.h"
 #include "well_known_classes.h"
 
 namespace art {
@@ -87,13 +88,14 @@
 // Common helper for class-loading cutouts in an unstarted runtime. We call Runtime methods that
 // rely on Java code to wrap errors in the correct exception class (i.e., NoClassDefFoundError into
 // ClassNotFoundException), so need to do the same. The only exception is if the exception is
-// actually InternalError. This must not be wrapped, as it signals an initialization abort.
+// actually the transaction abort exception. This must not be wrapped, as it signals an
+// initialization abort.
 static void CheckExceptionGenerateClassNotFound(Thread* self)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   if (self->IsExceptionPending()) {
-    // If it is not an InternalError, wrap it.
+    // If it is not the transaction abort exception, wrap it.
     std::string type(PrettyTypeOf(self->GetException()));
-    if (type != "java.lang.InternalError") {
+    if (type != Transaction::kAbortExceptionDescriptor) {
       self->ThrowNewWrappedException("Ljava/lang/ClassNotFoundException;",
                                      "ClassNotFoundException");
     }
@@ -502,7 +504,7 @@
   }
   if (!have_dex) {
     self->ClearException();
-    Runtime::Current()->AbortTransactionAndThrowInternalError(self, "Could not create Dex object");
+    Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Could not create Dex object");
   }
 }
 
@@ -570,7 +572,7 @@
   int64_t address_long = shadow_frame->GetVRegLong(arg_offset);
   mirror::Object* obj = shadow_frame->GetVRegReference(arg_offset + 2);
   if (obj == nullptr) {
-    Runtime::Current()->AbortTransactionAndThrowInternalError(self, "Null pointer in peekArray");
+    Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Null pointer in peekArray");
     return;
   }
   mirror::Array* array = obj->AsArray();
@@ -580,7 +582,7 @@
   if (offset < 0 || offset + count > array->GetLength()) {
     std::string error_msg(StringPrintf("Array out of bounds in peekArray: %d/%d vs %d",
                                        offset, count, array->GetLength()));
-    Runtime::Current()->AbortTransactionAndThrowInternalError(self, error_msg.c_str());
+    Runtime::Current()->AbortTransactionAndThrowAbortError(self, error_msg.c_str());
     return;
   }