Support compiling run-tests with jack

This CL adds support to compile run-test source files with jack. When
a test needs to rely on class files, we use jill to convert them to a
jack library.

We need to pass the full classpath to jack containing at least core
classes (like java.lang.Object). This means the Android tree must
have been compiled with jack first so we find all the necessary
classes.jack files.

Some tests still rely on dex files generated with the old toolchain.
We keep building them this way for the moment and will update them
later, when they get ready for Jack.

Also updates a few tests dealing with garbage collection to avoid a
situation where a reference can be retained by a local DEX register.

Bug: 19467889
Change-Id: I9eedd0705d1186d28a2acd37ea42a1762cd0ace2
diff --git a/test/run-test b/test/run-test
index ffa25eb..f5fff09a 100755
--- a/test/run-test
+++ b/test/run-test
@@ -46,6 +46,7 @@
 export RUN="${progdir}/etc/run-test-jar"
 export DEX_LOCATION=/data/run-test/${test_dir}
 export NEED_DEX="true"
+export USE_JACK="false"
 
 # If dx was not set by the environment variable, assume it is in the path.
 if [ -z "$DX" ]; then
@@ -67,6 +68,46 @@
   export DXMERGER="dexmerger"
 fi
 
+# If jack was not set by the environment variable, assume it is in the path.
+if [ -z "$JACK" ]; then
+  export JACK="jack"
+fi
+
+# If the tree is compiled with Jack, build test with Jack by default.
+if [ "$ANDROID_COMPILE_WITH_JACK" = "true" ]; then
+  USE_JACK="true"
+fi
+
+# ANDROID_BUILD_TOP is not set in a build environment.
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    export ANDROID_BUILD_TOP=$oldwd
+fi
+
+# If JACK_VM_COMMAND is not set, assume it launches the prebuilt jack-launcher.
+if [ -z "$JACK_VM_COMMAND" ]; then
+  if [ ! -z "$TMPDIR" ]; then
+    jack_temp_dir="-Djava.io.tmpdir=$TMPDIR"
+  fi
+  export JACK_VM_COMMAND="java -Dfile.encoding=UTF-8 -Xms2560m -XX:+TieredCompilation $jack_temp_dir -jar $ANDROID_BUILD_TOP/prebuilts/sdk/tools/jack-launcher.jar"
+fi
+
+# If JACK_CLASSPATH is not set, assume it only contains core-libart.
+if [ -z "$JACK_CLASSPATH" ]; then
+  export JACK_CLASSPATH="$ANDROID_BUILD_TOP/out/host/common/obj/JAVA_LIBRARIES/core-libart-hostdex_intermediates/classes.jack"
+fi
+
+# If JACK_JAR is not set, assume it is located in the prebuilts directory.
+if [ -z "$JACK_JAR" ]; then
+  export JACK_JAR="$ANDROID_BUILD_TOP/prebuilts/sdk/tools/jack.jar"
+fi
+
+# If JILL_JAR is not set, assume it is located in the prebuilts directory.
+if [ -z "$JILL_JAR" ]; then
+  export JILL_JAR="$ANDROID_BUILD_TOP/prebuilts/sdk/tools/jill.jar"
+fi
+
+export JACK="$JACK -g -cp $JACK_CLASSPATH"
+export JILL="java -jar $JILL_JAR"
 
 info="info.txt"
 build="build"
@@ -116,6 +157,7 @@
         runtime="jvm"
         prebuild_mode="no"
         NEED_DEX="false"
+        USE_JACK="false"
         run_args="${run_args} --jvm"
         shift
     elif [ "x$1" = "x-O" ]; then
@@ -237,6 +279,12 @@
     elif [ "x$1" = "x--build-only" ]; then
         build_only="yes"
         shift
+    elif [ "x$1" = "x--build-with-javac-dx" ]; then
+        USE_JACK="false"
+        shift
+    elif [ "x$1" = "x--build-with-jack" ]; then
+        USE_JACK="true"
+        shift
     elif [ "x$1" = "x--output-path" ]; then
         shift
         tmp_dir=$1
@@ -369,10 +417,7 @@
     fi
 elif [ "$runtime" = "art" ]; then
     if [ "$target_mode" = "no" ]; then
-        # ANDROID_BUILD_TOP and ANDROID_HOST_OUT are not set in a build environment.
-        if [ -z "$ANDROID_BUILD_TOP" ]; then
-            export ANDROID_BUILD_TOP=$oldwd
-        fi
+        # ANDROID_HOST_OUT is not set in a build environment.
         if [ -z "$ANDROID_HOST_OUT" ]; then
             export ANDROID_HOST_OUT=$ANDROID_BUILD_TOP/out/host/linux-x86
         fi
@@ -462,6 +507,8 @@
         echo "    --debuggable          Whether to compile Java code for a debugger."
         echo "    --gdb                 Run under gdb; incompatible with some tests."
         echo "    --build-only          Build test files only (off by default)."
+        echo "    --build-with-javac-dx Build test files with javac and dx (on by default)."
+        echo "    --build-with-jack     Build test files with jack and jill (off by default)."
         echo "    --interpreter         Enable interpreter only mode (off by default)."
         echo "    --jit                 Enable jit (off by default)."
         echo "    --optimizing          Enable optimizing compiler (default)."
@@ -556,6 +603,10 @@
   # if Checker is not invoked and the test only runs the program.
   build_args="${build_args} --dx-option --no-optimize"
 
+  # Jack does not necessarily generate the same DEX output than dx. Because these tests depend
+  # on a particular DEX output, keep building them with dx for now (b/19467889).
+  USE_JACK="false"
+
   if [ "$runtime" = "art" -a "$image_suffix" = "-optimizing" -a "$target_mode" = "no" -a "$debuggable" = "no" ]; then
     run_checker="yes"
     run_args="${run_args} -Xcompiler-option --dump-cfg=$tmp_dir/$cfg_output \
@@ -564,14 +615,20 @@
 fi
 
 # To cause tests to fail fast, limit the file sizes created by dx, dex2oat and ART output to 2MB.
-file_size_limit=2048
+build_file_size_limit=2048
+run_file_size_limit=2048
 if echo "$test_dir" | grep 089; then
-  file_size_limit=5120
+  build_file_size_limit=5120
+  run_file_size_limit=5120
 elif echo "$test_dir" | grep 083; then
-  file_size_limit=5120
+  build_file_size_limit=5120
+  run_file_size_limit=5120
 fi
-if ! ulimit -S "$file_size_limit"; then
-   echo "ulimit file size setting failed"
+if [ ${USE_JACK} = "false" ]; then
+  # Set ulimit if we build with dx only, Jack can generate big temp files.
+  if ! ulimit -S "$build_file_size_limit"; then
+    echo "ulimit file size setting failed"
+  fi
 fi
 
 good="no"
@@ -582,6 +639,9 @@
     build_exit="$?"
     echo "build exit status: $build_exit" 1>&2
     if [ "$build_exit" = '0' ]; then
+        if ! ulimit -S "$run_file_size_limit"; then
+          echo "ulimit file size setting failed"
+        fi
         echo "${test_dir}: running..." 1>&2
         "./${run}" $run_args "$@" 2>&1
         run_exit="$?"
@@ -604,6 +664,9 @@
     "./${build}" $build_args >"$build_output" 2>&1
     build_exit="$?"
     if [ "$build_exit" = '0' ]; then
+        if ! ulimit -S "$run_file_size_limit"; then
+          echo "ulimit file size setting failed"
+        fi
         echo "${test_dir}: running..." 1>&2
         "./${run}" $run_args "$@" >"$output" 2>&1
         if [ "$run_checker" = "yes" ]; then
@@ -635,6 +698,9 @@
     "./${build}" $build_args >"$build_output" 2>&1
     build_exit="$?"
     if [ "$build_exit" = '0' ]; then
+        if ! ulimit -S "$run_file_size_limit"; then
+          echo "ulimit file size setting failed"
+        fi
         echo "${test_dir}: running..." 1>&2
         "./${run}" $run_args "$@" >"$output" 2>&1
         run_exit="$?"