Fix transaction aborting
During compilation, a java.lang.InternalError is used to indicate
that class initialization failed and the enclosing transaction
should be aborted and the changes rolled back. However there is
nothing preventing the code executed from a class initializer from
catching that exception (like catching Throwable and ignore it).
Therefore we may return from the class initializer with no pending
exception, even if the transaction was aborted, and not rollback
the changes properly.
To fix this, we now rely on the new Transaction::aborted_ field to
know whether a transaction aborted. When returning from the class
initializer without pending exception, we now check wether we aborted
the enclosing transaction. If that's the case, we set the status of
the class to kStatusError and throw a new java.lang.InternalError
with the original abort message.
This CL also contains some cleanup:
- Renames Transaction::Abort to Transaction::Rollback which is less
ambiguous and more reflect what is done.
- Moves the code throwing the java.lang.InternalError exception into
the Transaction::ThrowInternalError method so we do not duplicate
code. Now we may abort transaction more than once (because we may
have caught the java.lang.InternalError then execute code causing
new transaction abort), we only keep the first abort message to
throw the exception.
- Updates transaction_test with more cases and more checks.
- Bumps oat version to force recompilation with this fix.
Bug: 19202032
Change-Id: Iedc6969528a68bbdf3123146e990df4dbc57834b
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 7451bd5..2d8c9d4 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1929,7 +1929,7 @@
*file_log << exception->Dump() << "\n";
}
soa.Self()->ClearException();
- transaction.Abort();
+ transaction.Rollback();
CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
}
}