From cbcfaf3a410e35730c4daeaff6c791665764925a Mon Sep 17 00:00:00 2001 From: buzbee Date: Mon, 19 Aug 2013 07:37:40 -0700 Subject: 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 --- test/109-suspend-check/expected.txt | 7 +++ test/109-suspend-check/info.txt | 2 + test/109-suspend-check/src/Main.java | 102 +++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 test/109-suspend-check/expected.txt create mode 100644 test/109-suspend-check/info.txt create mode 100644 test/109-suspend-check/src/Main.java (limited to 'test/109-suspend-check') 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; + } +} -- cgit v1.2.3