summaryrefslogtreecommitdiffstats
path: root/test/109-suspend-check
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2013-08-19 07:37:40 -0700
committerbuzbee <buzbee@google.com>2013-08-19 07:37:40 -0700
commitcbcfaf3a410e35730c4daeaff6c791665764925a (patch)
tree92f836a197f74ee912135fd4bb389cd261e6d4a5 /test/109-suspend-check
parent212ec8f32919d50a1e1cb7ea4b3b91ca938ae4e6 (diff)
downloadart-cbcfaf3a410e35730c4daeaff6c791665764925a.tar.gz
art-cbcfaf3a410e35730c4daeaff6c791665764925a.tar.bz2
art-cbcfaf3a410e35730c4daeaff6c791665764925a.zip
Fix suspend check optimization
Art's Quick compiler currently uses a convervative mechanism to ensure that a safe point will be reached within a "small" amount of time. Explicit suspend checks are placed prior to backwards branches and on returns. There are a lot of ways to optimize, which we'll get to in the future, but for now the only optimization is to detect a backwards branch that targets a return block. That's a common pattern in dex, and simple to detect. In those cases, we can suppress the suspend check on the backwards branch knowing that the return will do it. However, the notion of what is a backwards branch got a bit muddied with some mir optimizations that transform the graph by changing the sense of branches. What started off as a taken backwards branch may turn into a fallthrough backwards branch. This CL avoid the confusion by marking branches backwards based on their original dex targets rather than using the post-transform test of backwardness. Change-Id: I9b30be168c801af51bae7f66ecd442edcb115a18
Diffstat (limited to 'test/109-suspend-check')
-rw-r--r--test/109-suspend-check/expected.txt7
-rw-r--r--test/109-suspend-check/info.txt2
-rw-r--r--test/109-suspend-check/src/Main.java102
3 files changed, 111 insertions, 0 deletions
diff --git a/test/109-suspend-check/expected.txt b/test/109-suspend-check/expected.txt
new file mode 100644
index 0000000000..07cc8253da
--- /dev/null
+++ b/test/109-suspend-check/expected.txt
@@ -0,0 +1,7 @@
+Running (5 seconds) ...
+.
+.
+.
+.
+.
+Done.
diff --git a/test/109-suspend-check/info.txt b/test/109-suspend-check/info.txt
new file mode 100644
index 0000000000..d89d66aeda
--- /dev/null
+++ b/test/109-suspend-check/info.txt
@@ -0,0 +1,2 @@
+To support garbage collection, debugging and profiling the VM must be able to send all threads
+to a safepoint. This tests the ability of the VM to do this for a tight loop.
diff --git a/test/109-suspend-check/src/Main.java b/test/109-suspend-check/src/Main.java
new file mode 100644
index 0000000000..d92b9e5070
--- /dev/null
+++ b/test/109-suspend-check/src/Main.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+ private static final int TEST_TIME = 5;
+
+ public static void main(String[] args) {
+ System.out.println("Running (" + TEST_TIME + " seconds) ...");
+ InfiniteForLoop forLoop = new InfiniteForLoop();
+ InfiniteWhileLoop whileLoop = new InfiniteWhileLoop();
+ InfiniteDoWhileLoop doWhileLoop = new InfiniteDoWhileLoop();
+ MakeGarbage garbage = new MakeGarbage();
+ forLoop.start();
+ whileLoop.start();
+ doWhileLoop.start();
+ garbage.start();
+ for (int i = 0; i < TEST_TIME; i++) {
+ System.gc();
+ System.out.println(".");
+ sleep(1000);
+ }
+ forLoop.stopNow();
+ whileLoop.stopNow();
+ doWhileLoop.stopNow();
+ garbage.stopNow();
+ System.out.println("Done.");
+ }
+
+ public static void sleep(int ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException ie) {
+ System.err.println("sleep was interrupted");
+ }
+ }
+}
+
+class InfiniteWhileLoop extends Thread {
+ volatile private boolean keepGoing = true;
+ public void run() {
+ int i = 0;
+ while (keepGoing) {
+ i++;
+ }
+ }
+ public void stopNow() {
+ keepGoing = false;
+ }
+}
+
+class InfiniteDoWhileLoop extends Thread {
+ volatile private boolean keepGoing = true;
+ public void run() {
+ int i = 0;
+ do {
+ i++;
+ } while (keepGoing);
+ }
+ public void stopNow() {
+ keepGoing = false;
+ }
+}
+
+class InfiniteForLoop extends Thread {
+ int count = 100000;
+ volatile private boolean keepGoing = true;
+ public void run() {
+ int i = 0;
+ for (int j = 0; keepGoing; j++) {
+ i += j;
+ }
+ }
+ public void stopNow() {
+ keepGoing = false;
+ }
+}
+
+
+class MakeGarbage extends Thread {
+ volatile private boolean keepGoing = true;
+ public void run() {
+ while (keepGoing) {
+ byte[] garbage = new byte[100000];
+ }
+ }
+ public void stopNow() {
+ keepGoing = false;
+ }
+}