Abort transaction when Class.forName() fails.
And update VmClassLoader.findLoadedClass implementation in
UnstartedRuntime which has erroneously diverged since
https://android-review.googlesource.com/145075 .
Also prevent transactional interpreter from transfering
control to a catch handler for aborted transactions.
Also clean up Transaction::kAbortExceptionDescriptor naming
and some unused parameters.
Test: TransactionTest.CatchClassForNameAbortClass
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: Ibfc544283f5434efbaab238d11a6152ed2578050
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index 91eafab..ee7c591 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -54,7 +54,7 @@
ASSERT_TRUE(h_klass->IsInitialized());
h_klass.Assign(class_linker_->FindSystemClass(soa.Self(),
- Transaction::kAbortExceptionSignature));
+ Transaction::kAbortExceptionDescriptor));
ASSERT_TRUE(h_klass != nullptr);
class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
ASSERT_TRUE(h_klass->IsInitialized());
@@ -599,6 +599,18 @@
testTransactionAbort("LTransaction$MultipleNativeCallAbortClass;");
}
+// Tests failing class initialization due to Class.forName() not finding the class,
+// even if an "all" catch handler catches the exception thrown when aborting the transaction.
+TEST_F(TransactionTest, CatchClassForNameAbortClass) {
+ testTransactionAbort("LTransaction$CatchClassForNameAbortClass;");
+}
+
+// Same as CatchClassForNameAbortClass but the class initializer tries to do the work twice.
+// This would trigger a DCHECK() if we continued executing bytecode with an aborted transaction.
+TEST_F(TransactionTest, CatchClassForNameAbortClassTwice) {
+ testTransactionAbort("LTransaction$CatchClassForNameAbortClassTwice;");
+}
+
// Tests failing class initialization due to allocating instance of finalizable class.
TEST_F(TransactionTest, FinalizableAbortClass) {
testTransactionAbort("LTransaction$FinalizableAbortClass;");