summaryrefslogtreecommitdiffstats
path: root/test/Transaction
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-02-03 11:58:06 +0100
committerSebastien Hertz <shertz@google.com>2015-02-05 09:05:41 +0100
commit1c80becf5406cd6d95dc24bf47a0c5a3809ea281 (patch)
tree24853b3512e21b18df7a2401b174df891684334e /test/Transaction
parente5deafe9cdd81238c3916b04301ea884c93f46b5 (diff)
downloadart-1c80becf5406cd6d95dc24bf47a0c5a3809ea281.zip
art-1c80becf5406cd6d95dc24bf47a0c5a3809ea281.tar.gz
art-1c80becf5406cd6d95dc24bf47a0c5a3809ea281.tar.bz2
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
Diffstat (limited to 'test/Transaction')
-rw-r--r--test/Transaction/Transaction.java52
1 files changed, 48 insertions, 4 deletions
diff --git a/test/Transaction/Transaction.java b/test/Transaction/Transaction.java
index 9ca7fbf..00e1fbb 100644
--- a/test/Transaction/Transaction.java
+++ b/test/Transaction/Transaction.java
@@ -25,13 +25,57 @@ public class Transaction {
}
}
- static class BlacklistedClass {
+ static class FinalizableAbortClass {
+ public static AbortHelperClass finalizableObject;
static {
- NativeSupport.native_call();
+ finalizableObject = new AbortHelperClass();
}
}
- static class NativeSupport {
- public static native void native_call();
+ static class NativeCallAbortClass {
+ static {
+ AbortHelperClass.nativeMethod();
+ }
+ }
+
+ static class SynchronizedNativeCallAbortClass {
+ static {
+ synchronized (SynchronizedNativeCallAbortClass.class) {
+ AbortHelperClass.nativeMethod();
+ }
+ }
+ }
+
+ static class CatchNativeCallAbortClass {
+ static {
+ try {
+ AbortHelperClass.nativeMethod();
+ } catch (Throwable e) {
+ // ignore exception.
+ }
+ }
+ }
+
+ static class MultipleNativeCallAbortClass {
+ static {
+ // Call native method but catch the transaction exception.
+ try {
+ AbortHelperClass.nativeMethod();
+ } catch (Throwable e) {
+ // ignore exception.
+ }
+
+ // Call another native method.
+ AbortHelperClass.nativeMethod2();
+ }
+ }
+
+ // Helper class to abort transaction: finalizable class with natve methods.
+ static class AbortHelperClass {
+ public void finalize() throws Throwable {
+ super.finalize();
+ }
+ public static native void nativeMethod();
+ public static native void nativeMethod2();
}
}