Automated import from //branches/master/...@141983,141983
diff --git a/tests/072-precise-gc/expected.txt b/tests/072-precise-gc/expected.txt
new file mode 100644
index 0000000..18ec087
--- /dev/null
+++ b/tests/072-precise-gc/expected.txt
@@ -0,0 +1,2 @@
+Valid refs: 0
+String0String1String2String3String4String5String6String7String8String9
diff --git a/tests/072-precise-gc/info.txt b/tests/072-precise-gc/info.txt
new file mode 100644
index 0000000..b0b2cea
--- /dev/null
+++ b/tests/072-precise-gc/info.txt
@@ -0,0 +1 @@
+Try to detect whether precise GC is working.
diff --git a/tests/072-precise-gc/src/Main.java b/tests/072-precise-gc/src/Main.java
new file mode 100644
index 0000000..9b2315d
--- /dev/null
+++ b/tests/072-precise-gc/src/Main.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+import java.lang.ref.WeakReference;
+
+public class Main {
+    public static void main(String[] args) {
+        staleStackTest();
+    }
+
+    public static void staleStackTest() {
+        WeakReference wrefs[] = new WeakReference[10];
+
+        populate(wrefs);
+
+        check(wrefs);
+    }
+
+    static void populate(WeakReference[] wrefs) {
+        /*
+         * Get a bunch of non-constant String objects into registers.  These
+         * should be the first locals declared.
+         */
+        String str0 = generateString("String", 0);
+        String str1 = generateString("String", 1);
+        String str2 = generateString("String", 2);
+        String str3 = generateString("String", 3);
+        String str4 = generateString("String", 4);
+        String str5 = generateString("String", 5);
+        String str6 = generateString("String", 6);
+        String str7 = generateString("String", 7);
+        String str8 = generateString("String", 8);
+        String str9 = generateString("String", 9);
+
+        /* stuff them into the weak references array */
+        wrefs[0] = new WeakReference(str0);
+        wrefs[1] = new WeakReference(str1);
+        wrefs[2] = new WeakReference(str2);
+        wrefs[3] = new WeakReference(str3);
+        wrefs[4] = new WeakReference(str4);
+        wrefs[5] = new WeakReference(str5);
+        wrefs[6] = new WeakReference(str6);
+        wrefs[7] = new WeakReference(str7);
+        wrefs[8] = new WeakReference(str8);
+        wrefs[9] = new WeakReference(str9);
+    }
+
+    static String generateString(String base, int num) {
+        return base + num;
+    }
+
+    static void check(WeakReference[] wrefs) {
+        /*
+         * Declare locals so that our stack overlaps the same region
+         * that populate() did.
+         */
+        String str0;
+        String str1;
+        String str2;
+        String str3;
+        String str4;
+        String str5;
+        String str6;
+        String str7;
+        String str8;
+        String str9;
+        int numValid = 0;
+
+        /*
+         * This *should* blow out all the weakly-reference objects.  If
+         * we still have stale copies of references on the stack, a
+         * conservative GC will try to hold on to those objects and the
+         * count will be nonzero.
+         *
+         * Getting a zero result here isn't conclusive, but it's a strong
+         * indicator that precise GC is having an impact.
+         */
+        System.gc();
+
+        for (int i = 0; i < wrefs.length; i++) {
+            if (wrefs[i].get() != null)
+                numValid++;
+        }
+
+        System.out.println("Valid refs: " + numValid);
+
+        /* use the locals in case the compiler gets smart */
+        str0 = generateString("String", 0);
+        str1 = generateString("String", 1);
+        str2 = generateString("String", 2);
+        str3 = generateString("String", 3);
+        str4 = generateString("String", 4);
+        str5 = generateString("String", 5);
+        str6 = generateString("String", 6);
+        str7 = generateString("String", 7);
+        str8 = generateString("String", 8);
+        str9 = generateString("String", 9);
+        System.out.println(str0+str1+str2+str3+str4+str5+str6+str7+str8+str9);
+    }
+}
+
diff --git a/tests/etc/local-run-test-jar b/tests/etc/local-run-test-jar
index 0c802ba..641306d 100755
--- a/tests/etc/local-run-test-jar
+++ b/tests/etc/local-run-test-jar
@@ -26,6 +26,7 @@
 VALGRIND="n"
 DEV_MODE="n"
 QUIET="n"
+PRECISE="y"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -57,6 +58,9 @@
     elif [ "x$1" = "x--no-optimize" ]; then
         OPTIMIZE="n"
         shift
+    elif [ "x$1" = "x--no-precise" ]; then
+        PRECISE="n"
+        shift
     elif [ "x$1" = "x--" ]; then
         shift
         break
@@ -101,6 +105,12 @@
     valgrind_cmd=""
 fi
 
+if [ "$PRECISE" = "y" ]; then
+    GC_OPTS="-Xgc:precise -Xgenregmap"
+else
+    GC_OPTS="-Xgc:noprecise"
+fi
+
 msg "------------------------------"
 
 BASE="$OUT" # from build environment
@@ -109,9 +119,9 @@
 
 export ANDROID_PRINTF_LOG=brief
 if [ "$DEV_MODE" = "y" ]; then
-	export ANDROID_LOG_TAGS='*:d'
+    export ANDROID_LOG_TAGS='*:d'
 else
-	export ANDROID_LOG_TAGS='*:s'
+    export ANDROID_LOG_TAGS='*:s'
 fi
 export ANDROID_DATA="$DATA_DIR"
 export ANDROID_ROOT="${BASE}/system"
@@ -134,5 +144,5 @@
 fi
 
 $valgrind_cmd $gdb $exe $gdbargs "-Xbootclasspath:${bpath}" \
-    $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG "-Xint:${INTERP}" -ea \
+    $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG $GC_OPTS "-Xint:${INTERP}" -ea \
     -cp test.jar Main "$@"
diff --git a/tests/etc/push-and-run-test-jar b/tests/etc/push-and-run-test-jar
index e2a1e06..a7dc9af 100755
--- a/tests/etc/push-and-run-test-jar
+++ b/tests/etc/push-and-run-test-jar
@@ -24,6 +24,7 @@
 OPTIMIZE="y"
 ZYGOTE="n"
 QUIET="n"
+PRECISE="y"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -50,6 +51,9 @@
     elif [ "x$1" = "x--no-optimize" ]; then
         OPTIMIZE="n"
         shift
+    elif [ "x$1" = "x--no-precise" ]; then
+        PRECISE="n"
+        shift
     elif [ "x$1" = "x--" ]; then
         shift
         break
@@ -102,9 +106,15 @@
     DEX_DEBUG="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y"
 fi
 
+if [ "$PRECISE" = "y" ]; then
+    GC_OPTS="-Xgc:precise -Xgenregmap"
+else
+    GC_OPTS="-Xgc:noprecise"
+fi
+
 if [ "$ZYGOTE" = "y" ]; then
     adb shell cd /data \; dvz -classpath test.jar Main "$@"
 else
     adb shell cd /data \; dalvikvm $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG \
-        -cp test.jar "-Xint:${INTERP}" -ea Main "$@"
+        $GC_OPTS -cp test.jar "-Xint:${INTERP}" -ea Main "$@"
 fi
diff --git a/tests/run-test b/tests/run-test
index b503905..25bfb4e 100755
--- a/tests/run-test
+++ b/tests/run-test
@@ -79,6 +79,9 @@
     elif [ "x$1" = "x--no-optimize" ]; then
         run_args="${run_args} --no-optimize"
         shift
+    elif [ "x$1" = "x--no-precise" ]; then
+        run_args="${run_args} --no-precise"
+        shift
     elif [ "x$1" = "x--valgrind" ]; then
         run_args="${run_args} --valgrind"
         shift
@@ -146,6 +149,7 @@
         #echo "    --gdb          Run under gdb; incompatible with some tests."
         echo "    --no-verify    Turn off verification (on by default)."
         echo "    --no-optimize  Turn off optimization (on by default)."
+        echo "    --no-precise   Turn off precise GC (on by default)."
         echo "    --zygote       Spawn the process from the Zygote." \
 	    "If used, then the"
 	echo "                   other runtime options are ignored."