run-test: Build against libcore for Android device and host targets.

--jvm will build against the RI bootclasspath
--host will build against the host libcore bootclasspath
(implied --target) will build against the target libcore bootclasspath

Also fix other tests that were relying on building against OpenJDK.

Bug: 72491947
Test: art/test/testrunner/testrunner.py --jvm
Test: art/test/testrunner/testrunner.py --host
Change-Id: Ib7ce6740cda544797604200341578f8191f4b2b4
diff --git a/test/636-arm64-veneer-pool/build b/test/636-arm64-veneer-pool/build
index eba22fc..43f9018 100755
--- a/test/636-arm64-veneer-pool/build
+++ b/test/636-arm64-veneer-pool/build
@@ -24,4 +24,4 @@
 # on a platform build compiled with ANDROID_COMPILE_WITH_JACK=true.
 export USE_DESUGAR=false
 
-./default-build
+./default-build "$@"
diff --git a/test/641-checker-arraycopy/src/Main.java b/test/641-checker-arraycopy/src/Main.java
index f0fcf28..c2a95cc 100644
--- a/test/641-checker-arraycopy/src/Main.java
+++ b/test/641-checker-arraycopy/src/Main.java
@@ -27,7 +27,7 @@
   /// CHECK: ReturnVoid
   public static void typedCopy(Object o, byte[] foo) {
     System.arraycopy(o, 1, o, 0, 1);
-    System.arraycopy(foo, 1, foo, 0, 1);
+    System.arraycopy((Object)foo, 1, (Object)foo, 0, 1);  // Don't use the @hide byte[] overload.
   }
 
   public static void untypedCopy(Object o, Object foo) {
diff --git a/test/674-hiddenapi/build b/test/674-hiddenapi/build
index 330a6de..9012e8f 100644
--- a/test/674-hiddenapi/build
+++ b/test/674-hiddenapi/build
@@ -16,6 +16,15 @@
 
 set -e
 
+# Special build logic to handle src-ex .java files which have code that only builds on RI.
+custom_build_logic() {
+  [[ -d ignore.src-ex ]] && mv ignore.src-ex src-ex
+  # src-ex uses code that can only build on RI.
+  ${JAVAC} -source 1.8 -target 1.8 -sourcepath src-ex -sourcepath src -d classes-ex $(find src-ex -name '*.java')
+  # remove src-ex so that default-build doesn't try to build it.
+  [[ -d src-ex ]] && mv src-ex ignore.src-ex
+}
+
 # Build the jars twice. First with applying hiddenapi, creating a boot jar, then
 # a second time without to create a normal jar. We need to do this because we
 # want to load the jar once as an app module and once as a member of the boot
@@ -24,6 +33,7 @@
 # class path dex files, so the boot jar loads fine in the latter case.
 
 export USE_HIDDENAPI=true
+custom_build_logic
 ./default-build "$@"
 
 # Move the jar file into the resource folder to be bundled with the test.
@@ -35,4 +45,5 @@
 rm -rf classes*
 
 export USE_HIDDENAPI=false
+custom_build_logic
 ./default-build "$@"
diff --git a/test/988-method-trace/check b/test/988-method-trace/check
index 4c583eb..de64a3e 100644
--- a/test/988-method-trace/check
+++ b/test/988-method-trace/check
@@ -14,8 +14,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Jack uses @hide API which gives it wrong method trace in the expected.txt
-if [[ "$USE_JACK" == true ]]; then
+# Building for libcore, this uses @hide API which gives it wrong method trace in the expected.txt
+# TODO: would be nice if we could build against core_current jars in the future to avoid this.
+if [[ "$NEED_DEX" == true ]]; then
   patch -p0 expected.txt < expected_jack.diff >/dev/null
 fi
 
diff --git a/test/etc/default-build b/test/etc/default-build
index 6040f7d..4ed2af6 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -17,6 +17,12 @@
 # Stop if something fails.
 set -e
 
+if [[ $# -le 0 ]]; then
+  echo 'Error:' '$0 should have the parameters from the "build" script forwarded to it' >&2
+  echo 'Error: An example of how do it correctly is ./default-build "$@"'
+  exit 1
+fi
+
 # Set default values for directories.
 if [ -d smali ]; then
   HAS_SMALI=true
@@ -150,8 +156,6 @@
     option="$1"
     DX_VM_FLAGS="${DX_VM_FLAGS} $option"
     shift
-  elif [ "x$1" = "x--jvm" ]; then
-    shift
   elif [ "x$1" = "x--no-src" ]; then
     HAS_SRC=false
     shift
@@ -193,6 +197,9 @@
   elif [ "x$1" = "x--target" ]; then
     BUILD_MODE="target"
     shift
+  elif [ "x$1" = "x--jvm" ]; then
+    BUILD_MODE="jvm"
+    shift
   elif [ "x$1" = "x--dev" ]; then
     DEV_MODE="yes"
     shift
@@ -204,6 +211,13 @@
   fi
 done
 
+if [[ $BUILD_MODE == jvm ]]; then
+  # Does not need desugar on jvm because it supports the latest functionality.
+  USE_DESUGAR=false
+  # Do not attempt to build src-art directories on jvm, it would fail without libcore.
+  HAS_SRC_ART=false
+fi
+
 # Be sure to get any default arguments if not doing any experiments.
 EXPERIMENTAL="${EXPERIMENTAL} ${DEFAULT_EXPERIMENT}"
 
@@ -261,10 +275,7 @@
 }
 
 function desugar() {
-  local desugar_args=--mode=host
-  if [[ $BUILD_MODE == target ]]; then
-    desugar_args=--mode=target
-  fi
+  local desugar_args="--mode=$BUILD_MODE"
 
   if [[ $DEV_MODE == yes ]]; then
     desugar_args="$desugar_args --show-commands"
@@ -273,18 +284,16 @@
   "$DESUGAR" --core-only $desugar_args "$@"
 }
 
-# Like regular javac but includes libcore on the bootclasspath.
+# Like regular javac but may include libcore on the bootclasspath.
 function javac_with_bootclasspath {
-  local javac_args=--mode=host
-  if [[ $BUILD_MODE == target ]]; then
-    javac_args=--mode=target
-  fi
+  local helper_args="--mode=$BUILD_MODE"
 
   if [[ $DEV_MODE == yes ]]; then
-    javac_args="$javac_args --show-commands"
+    helper_args="$helper_args --show-commands"
   fi
 
-  "$ANDROID_BUILD_TOP/art/tools/javac-helper.sh" --core-only $javac_args "$@"
+  # build with libcore for host and target, or openjdk for jvm
+  "$ANDROID_BUILD_TOP/art/tools/javac-helper.sh" --core-only $helper_args ${JAVAC_ARGS} "$@"
 }
 
 # Make a "dex" file given a directory of classes in $1.
@@ -373,10 +382,10 @@
 }
 
 if [ ${HAS_SRC_DEX2OAT_UNRESOLVED} = "true" ]; then
-  mkdir classes
+  mkdir -p classes
   mkdir classes-ex
-  ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src-dex2oat-unresolved -d classes `find src -name '*.java'`
-  ${JAVAC} ${JAVAC_ARGS} -implicit:none -sourcepath src -d classes-ex `find src-dex2oat-unresolved -name '*.java'`
+  javac_with_bootclasspath -implicit:none -sourcepath src-dex2oat-unresolved -d classes `find src -name '*.java'`
+  javac_with_bootclasspath -implicit:none -sourcepath src -d classes-ex `find src-dex2oat-unresolved -name '*.java'`
   if [ ${USE_JACK} = "true" ]; then
     jar cf classes.jill.jar -C classes .
     jar cf classes-ex.jill.jar -C classes-ex .
@@ -424,18 +433,18 @@
   else
     # Legacy toolchain with javac+dx
     if [ "${HAS_SRC}" = "true" ]; then
-      mkdir classes
-      ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'`
+      mkdir -p classes
+      javac_with_bootclasspath -implicit:none -classpath src-multidex -d classes `find src -name '*.java'`
     fi
 
     if [ "${HAS_SRC_ART}" = "true" ]; then
       mkdir -p classes
-      javac_with_bootclasspath ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src-art -name '*.java'`
+      javac_with_bootclasspath -implicit:none -classpath src-multidex -d classes `find src-art -name '*.java'`
     fi
 
     if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
       mkdir classes2
-      ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'`
+      javac_with_bootclasspath -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'`
       if [ ${NEED_DEX} = "true" ]; then
         make_dex classes2
       fi
@@ -443,7 +452,7 @@
 
     if [ "${HAS_SRC2}" = "true" ]; then
       mkdir -p classes
-      ${JAVAC} ${JAVAC_ARGS} -classpath classes -d classes `find src2 -name '*.java'`
+      javac_with_bootclasspath -classpath classes -d classes `find src2 -name '*.java'`
     fi
 
     if [[ "${HAS_SRC}" == "true" || "${HAS_SRC2}" == "true" || "${HAS_SRC_ART}" == "true" ]]; then
@@ -516,29 +525,30 @@
     # Includes 'src', 'src-art' source when compiling classes-ex, but exclude their .class files.
     if [[ "${HAS_SRC}" == "true" ]]; then
       mkdir -p classes-tmp-for-ex
-      ${JAVAC} ${JAVAC_ARGS} -d classes-tmp-for-ex `find src -name '*.java'`
+      javac_with_bootclasspath -d classes-tmp-for-ex `find src -name '*.java'`
       src_tmp_for_ex="-cp classes-tmp-for-ex"
     fi
     if [[ "${HAS_SRC_ART}" == "true" ]]; then
       mkdir -p classes-tmp-for-ex
-      javac_with_bootclasspath ${JAVAC_ARGS} -d classes-tmp-for-ex `find src-art -name '*.java'`
+      javac_with_bootclasspath -d classes-tmp-for-ex `find src-art -name '*.java'`
       src_tmp_for_ex="-cp classes-tmp-for-ex"
     fi
     mkdir classes-ex
-    ${JAVAC} ${JAVAC_ARGS} -d classes-ex $src_tmp_for_ex `find src-ex -name '*.java'`
-    if [ ${NEED_DEX} = "true" ]; then
-      make_dex classes-ex
-
-      # quick shuffle so that the stored name is "classes.dex"
-      mv classes.dex classes-1.dex
-      mv classes-ex.dex classes.dex
-      zip $TEST_NAME-ex.jar classes.dex
-      mv classes.dex classes-ex.dex
-      mv classes-1.dex classes.dex
-    fi
+    javac_with_bootclasspath -d classes-ex $src_tmp_for_ex `find src-ex -name '*.java'`
   fi
 fi
 
+if [[ -d classes-ex ]] && [ ${NEED_DEX} = "true" ]; then
+  make_dex classes-ex
+
+  # quick shuffle so that the stored name is "classes.dex"
+  mv classes.dex classes-1.dex
+  mv classes-ex.dex classes.dex
+  zip $TEST_NAME-ex.jar classes.dex
+  mv classes.dex classes-ex.dex
+  mv classes-1.dex classes.dex
+fi
+
 # Apply hiddenapi on the dex files if the test has API list file(s).
 if [ ${NEED_DEX} = "true" -a ${USE_HIDDENAPI} = "true" -a ${HAS_HIDDENAPI_SPEC} = "true" ]; then
   if $(has_multidex); then
diff --git a/test/run-test b/test/run-test
index 6bcb9cd..260a65a 100755
--- a/test/run-test
+++ b/test/run-test
@@ -195,7 +195,6 @@
         NEED_DEX="false"
         USE_JACK="false"
         run_args="${run_args} --jvm"
-        build_args="${build_args} --jvm"
         shift
     elif [ "x$1" = "x-O" ]; then
         lib="libart.so"
@@ -836,10 +835,16 @@
   err_echo "ulimit file size setting failed"
 fi
 
+# Tell the build script which mode (target, host, jvm) we are building for
+# to determine the bootclasspath at build time.
 if [[ "$target_mode" == "yes" ]]; then
   build_args="$build_args --target"
 else
-  build_args="$build_args --host"
+  if [[ $runtime == "jvm" ]]; then
+    build_args="$build_args --jvm"
+  else
+    build_args="$build_args --host"
+  fi
 fi
 
 if [[ "$dev_mode" == "yes" ]]; then
diff --git a/tools/desugar.sh b/tools/desugar.sh
index ae7bf0a..7f73852 100755
--- a/tools/desugar.sh
+++ b/tools/desugar.sh
@@ -59,6 +59,10 @@
     --mode=target)
       bootjars_args="$bootjars_args --target"
       ;;
+    --mode=*)
+      echo "Unsupported $0 usage with --mode=$1" >&2
+      exit 1
+      ;;
     --core-only)
       bootjars_args="$bootjars_args --core"
       ;;
diff --git a/tools/javac-helper.sh b/tools/javac-helper.sh
index 2d71d35..03ea829 100755
--- a/tools/javac-helper.sh
+++ b/tools/javac-helper.sh
@@ -17,12 +17,15 @@
 #
 # Calls javac with the -bootclasspath values passed in automatically.
 # (This avoids having to manually set a boot class path).
+# If $JAVAC is set, it will call that instead of 'javac'.
 #
 #
 # Script-specific args:
-#   --mode=[host|target]: Select between host or target bootclasspath (default target).
+#   --mode=[host|target|jvm]:
+#                         Select between host,target,jvm bootclasspath (default target).
 #   --core-only:          Use only "core" bootclasspath (e.g. do not include framework).
-#   --show-commands:      Print the desugar command being executed.
+#                         Ignored with --mode=jvm.
+#   --show-commands:      Print the javac command being executed.
 #   --help:               Print above list of args.
 #
 # All other args are forwarded to javac
@@ -41,14 +44,23 @@
 while true; do
   case $1 in
     --help)
-      echo "Usage: $0 [--mode=host|target] [--core-only] [--show-commands] <javac args>"
+      echo "Usage: $0 [--mode=host|target|jvm] [--core-only] [--show-commands] <javac args>"
       exit 0
       ;;
     --mode=host)
       bootjars_args="$bootjars_args --host"
+      mode=host
       ;;
     --mode=target)
       bootjars_args="$bootjars_args --target"
+      mode=target
+      ;;
+    --mode=jvm)
+      mode=jvm
+      ;;
+    --mode=*)
+      echo "Unsupported $0 usage with --mode=$1" >&2
+      exit 1
       ;;
     --core-only)
       bootjars_args="$bootjars_args --core"
@@ -63,23 +75,29 @@
   shift
 done
 
-javac_bootclasspath=()
-boot_class_path_list=$($TOP/art/tools/bootjars.sh $bootjars_args --path)
+if [[ $mode == jvm ]]; then
+  # For --mode=jvm:
+  # Do not prepend a -bootclasspath, which will use the default bootclasspath instead.
+  javac_args=()
+else
+  # For --mode=host or --mode=target, look up the correct -bootclasspath for libcore.
+  javac_bootclasspath=()
+  boot_class_path_list=$($TOP/art/tools/bootjars.sh $bootjars_args --path)
 
+  for path in $boot_class_path_list; do
+    javac_bootclasspath+=("$path")
+  done
 
-for path in $boot_class_path_list; do
-  javac_bootclasspath+=("$path")
-done
+  if [[ ${#javac_bootclasspath[@]} -eq 0 ]]; then
+    echo "FATAL: Missing bootjars.sh file path list" >&2
+    exit 1
+  fi
 
-if [[ ${#javac_bootclasspath[@]} -eq 0 ]]; then
-  echo "FATAL: Missing bootjars.sh file path list" >&2
-  exit 1
+  function join_by { local IFS="$1"; shift; echo "$*"; }
+  bcp_arg="$(join_by ":" "${javac_bootclasspath[@]}")"
+  javac_args=(-bootclasspath "$bcp_arg")
 fi
 
-function join_by { local IFS="$1"; shift; echo "$*"; }
-bcp_arg="$(join_by ":" "${javac_bootclasspath[@]}")"
-javac_args=(-bootclasspath "$bcp_arg")
-
 if [[ $showcommands == y ]]; then
   echo ${JAVAC} "${javac_args[@]}" "$@"
 fi