ART: Add complex UnresolvedMergedType test case
Add a test case that stresses the verifier. Add dex2oat timeout
to the host prebuild configuration.
Bug: 22881413
Change-Id: Ic4a0d16a4dc69f3d43bac40a560b6e6884df263f
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index 728ccea..884f280 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -37,4 +37,5 @@
b/22411633 (4)
b/22411633 (5)
b/22777307
+b/22881413
Done!
diff --git a/test/800-smali/smali/b_22881413.smali b/test/800-smali/smali/b_22881413.smali
new file mode 100644
index 0000000..f624734
--- /dev/null
+++ b/test/800-smali/smali/b_22881413.smali
@@ -0,0 +1,291 @@
+.class public LB22881413;
+.super Ljava/lang/Object;
+
+# A couple of fields to allow "loading" resolved and unresolved types. Use non-final classes to
+# avoid automatically getting precise reference types.
+.field private static res1:Ljava/lang/Number;
+.field private static res2:Ljava/lang/ClassLoader;
+.field private static res3:Ljava/lang/Package;
+.field private static res4:Ljava/lang/RuntimeException;
+.field private static res5:Ljava/lang/Exception;
+.field private static res6:Ljava/util/ArrayList;
+.field private static res7:Ljava/util/LinkedList;
+.field private static res8:Ljava/lang/Thread;
+.field private static res9:Ljava/lang/ThreadGroup;
+.field private static res10:Ljava/lang/Runtime;
+
+.field private static unres1:La/b/c/d1;
+.field private static unres2:La/b/c/d2;
+.field private static unres3:La/b/c/d3;
+.field private static unres4:La/b/c/d4;
+.field private static unres5:La/b/c/d5;
+.field private static unres6:La/b/c/d6;
+.field private static unres7:La/b/c/d7;
+.field private static unres8:La/b/c/d8;
+.field private static unres9:La/b/c/d9;
+.field private static unres10:La/b/c/d10;
+
+.field private static unresBase0:La/b/c/dBase0;
+.field private static unresBase1:La/b/c/dBase1;
+.field private static unresBase2:La/b/c/dBase2;
+.field private static unresBase3:La/b/c/dBase3;
+.field private static unresBase4:La/b/c/dBase4;
+.field private static unresBase5:La/b/c/dBase5;
+.field private static unresBase6:La/b/c/dBase6;
+.field private static unresBase7:La/b/c/dBase7;
+.field private static unresBase8:La/b/c/dBase8;
+
+# Empty, ignore this. We want to see if the other method can be verified in a reasonable amount of
+# time.
+.method public static run()V
+.registers 2
+ return-void
+.end method
+
+.method public static foo(IZZ) V
+.registers 11
+ # v8 = int, v9 = boolean, v10 = boolean
+
+ sget-object v0, LB22881413;->unresBase0:La/b/c/dBase0;
+ const v1, 0
+ const v2, 0
+
+# We're trying to create something like this (with more loops to amplify things).
+#
+# v0 = Unresolved1
+# while (something) {
+#
+# [Repeatedly]
+# if (cond) {
+# v0 = ResolvedX;
+# } else {
+# v0 = UnresolvedX;
+# }
+#
+# v0 = Unresolved2
+# };
+#
+# Important points:
+# 1) Use a while, so that the end of the loop is a goto. That way, the merging of outer-loop
+# unresolved classes is postponed.
+# 2) Put the else cases after all if cases. That way there are backward gotos that will lead
+# to stabilization loops in the body.
+#
+
+:Loop1
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop1End
+
+:Loop2
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop2End
+
+:Loop3
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop3End
+
+:Loop4
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop4End
+
+:Loop5
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop5End
+
+:Loop6
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop6End
+
+:Loop7
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop7End
+
+:Loop8
+
+ const v6, 0
+ add-int/lit16 v8, v8, -1
+ if-ge v8, v6, :Loop8End
+
+# Prototype:
+#
+# if-eqz v9, :ElseX
+# sget-object v0, LB22881413;->res1:Ljava/lang/Number;
+#:JoinX
+#
+# And somewhere at the end
+#
+#:ElseX
+# sget-object v0, LB22881413;->unresX:La/b/c/dX;
+# goto :JoinX
+#
+#
+
+ if-eqz v10, :Join1
+ if-eqz v9, :Else1
+ sget-object v0, LB22881413;->res1:Ljava/lang/Number;
+:Join1
+
+
+ if-eqz v10, :Join2
+ if-eqz v9, :Else2
+ sget-object v0, LB22881413;->res2:Ljava/lang/ClassLoader;
+:Join2
+
+
+ if-eqz v10, :Join3
+ if-eqz v9, :Else3
+ sget-object v0, LB22881413;->res3:Ljava/lang/Package;
+:Join3
+
+
+ if-eqz v10, :Join4
+ if-eqz v9, :Else4
+ sget-object v0, LB22881413;->res4:Ljava/lang/RuntimeException;
+:Join4
+
+
+ if-eqz v10, :Join5
+ if-eqz v9, :Else5
+ sget-object v0, LB22881413;->res5:Ljava/lang/Exception;
+:Join5
+
+
+ if-eqz v10, :Join6
+ if-eqz v9, :Else6
+ sget-object v0, LB22881413;->res6:Ljava/util/ArrayList;
+:Join6
+
+
+ if-eqz v10, :Join7
+ if-eqz v9, :Else7
+ sget-object v0, LB22881413;->res7:Ljava/util/LinkedList;
+:Join7
+
+
+ if-eqz v10, :Join8
+ if-eqz v9, :Else8
+ sget-object v0, LB22881413;->res8:Ljava/lang/Thread;
+:Join8
+
+
+ if-eqz v10, :Join9
+ if-eqz v9, :Else9
+ sget-object v0, LB22881413;->res9:Ljava/lang/ThreadGroup;
+:Join9
+
+
+ if-eqz v10, :Join10
+ if-eqz v9, :Else10
+ sget-object v0, LB22881413;->res10:Ljava/lang/Runtime;
+:Join10
+
+
+ goto :InnerMostLoopEnd
+
+:Else1
+ sget-object v0, LB22881413;->unres1:La/b/c/d1;
+ goto :Join1
+
+:Else2
+ sget-object v0, LB22881413;->unres2:La/b/c/d2;
+ goto :Join2
+
+:Else3
+ sget-object v0, LB22881413;->unres3:La/b/c/d3;
+ goto :Join3
+
+:Else4
+ sget-object v0, LB22881413;->unres4:La/b/c/d4;
+ goto :Join4
+
+:Else5
+ sget-object v0, LB22881413;->unres5:La/b/c/d5;
+ goto :Join5
+
+:Else6
+ sget-object v0, LB22881413;->unres6:La/b/c/d6;
+ goto :Join6
+
+:Else7
+ sget-object v0, LB22881413;->unres7:La/b/c/d7;
+ goto :Join7
+
+:Else8
+ sget-object v0, LB22881413;->unres8:La/b/c/d8;
+ goto :Join8
+
+:Else9
+ sget-object v0, LB22881413;->unres9:La/b/c/d9;
+ goto :Join9
+
+:Else10
+ sget-object v0, LB22881413;->unres10:La/b/c/d10;
+ goto :Join10
+
+:InnerMostLoopEnd
+
+ # Loop 8 end of body.
+ sget-object v0, LB22881413;->unresBase8:La/b/c/dBase8;
+ goto :Loop8
+
+:Loop8End
+
+ # Loop 7 end of body.
+ sget-object v0, LB22881413;->unresBase7:La/b/c/dBase7;
+ goto :Loop7
+
+:Loop7End
+
+ # Loop 6 end of body.
+ sget-object v0, LB22881413;->unresBase6:La/b/c/dBase6;
+ goto :Loop6
+
+:Loop6End
+
+ # Loop 5 end of body
+ sget-object v0, LB22881413;->unresBase5:La/b/c/dBase5;
+ goto :Loop5
+
+:Loop5End
+
+ # Loop 4 end of body
+ sget-object v0, LB22881413;->unresBase4:La/b/c/dBase4;
+ goto :Loop4
+
+:Loop4End
+
+ # Loop 3 end of body
+ sget-object v0, LB22881413;->unresBase3:La/b/c/dBase3;
+ goto :Loop3
+
+:Loop3End
+
+ # Loop 2 end of body
+ sget-object v0, LB22881413;->unresBase2:La/b/c/dBase2;
+ goto :Loop2
+
+:Loop2End
+
+ # Loop 1 end of body
+ sget-object v0, LB22881413;->unresBase1:La/b/c/dBase1;
+ goto :Loop1
+
+:Loop1End
+
+ return-void
+
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index 438e214..e1ac749 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -121,6 +121,7 @@
null, null));
testCases.add(new TestCase("b/22777307", "B22777307", "run", null, new InstantiationError(),
null));
+ testCases.add(new TestCase("b/22881413", "B22881413", "run", null, null, null));
}
public void runTests() {
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 750a29f..a1af577 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -338,6 +338,17 @@
if [ "x$INSTRUCTION_SET_FEATURES" != "x" ] ; then
dex2oat_cmdline="${dex2oat_cmdline} --instruction-set-features=${INSTRUCTION_SET_FEATURES}"
fi
+
+ # Add in a timeout. This is important for testing the compilation/verification time of
+ # pathological cases.
+ # Note: as we don't know how decent targets are (e.g., emulator), only do this on the host for
+ # now. We should try to improve this.
+ # The current value is rather arbitrary. run-tests should compile quickly.
+ if [ "$HOST" != "n" ]; then
+ # Use SIGRTMIN+2 to try to dump threads.
+ # Use -k 1m to SIGKILL it a minute later if it hasn't ended.
+ dex2oat_cmdline="timeout -k 1m -s SIGRTMIN+2 1m ${dex2oat_cmdline}"
+ fi
fi
DALVIKVM_ISA_FEATURES_ARGS=""