Revert^2 "Improve user-friendliness of art script."
Fixes quoting for mksh for arguments with whitespace.
Test: art/tools/run-jdwp-tests.sh --mode=device
Change-Id: I0b8983a0c0ebcc1b64ad943859fbb85d3774ab75
diff --git a/tools/art b/tools/art
index f5e0860..6e62ad1 100644
--- a/tools/art
+++ b/tools/art
@@ -16,6 +16,15 @@
# shell dialect that should work on the host (e.g. bash), and
# Android (e.g. mksh).
+# Globals
+ARCHS={arm,arm64,mips,mips64,x86,x86_64}
+ART_BINARY=dalvikvm
+DELETE_ANDROID_DATA="no"
+LAUNCH_WRAPPER=
+LIBART=libart.so
+JIT_PROFILE="no"
+VERBOSE="no"
+
# Follow all sym links to get the program name.
if [ z"$BASH_SOURCE" != z ]; then
PROG_NAME="$BASH_SOURCE"
@@ -28,16 +37,15 @@
done
function find_libdir() {
- # Get the actual file, $DALVIKVM may be a symbolic link.
+ # Get the actual file, $1 is the ART_BINARY_PATH and may be a symbolic link.
# Use realpath instead of readlink because Android does not have a readlink.
- if [[ "$(realpath "$ANDROID_ROOT/bin/$DALVIKVM")" == *dalvikvm64 ]]; then
+ if [[ "$(realpath "$1")" == *dalvikvm64 ]]; then
echo "lib64"
else
echo "lib"
fi
}
-ARGS_WITH_INTERPRET_ONLY=
function replace_compiler_filter_with_interepret_only() {
ARGS_WITH_INTERPRET_ONLY=("$@")
@@ -61,65 +69,156 @@
fi
}
-invoke_with=
-DALVIKVM=dalvikvm
-LIBART=libart.so
-JIT_PROFILE=false
+function usage() {
+ cat 1>&2 <<EOF
+Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS
-while true; do
- if [ "$1" = "--invoke-with" ]; then
- shift
- invoke_with="$invoke_with $1"
- shift
- elif [ "$1" = "-d" ]; then
- LIBART="libartd.so"
- shift
- elif [ "$1" = "--32" ]; then
- DALVIKVM=dalvikvm32
- shift
- elif [ "$1" = "--64" ]; then
- DALVIKVM=dalvikvm64
- shift
- elif [ "$1" = "--perf" ]; then
- PERF="record"
- shift
- elif [ "$1" = "--perf-report" ]; then
- PERF="report"
- shift
- elif [ "$1" = "--profile" ]; then
- JIT_PROFILE="true"
- shift
- elif expr "$1" : "--" >/dev/null 2>&1; then
- echo "unknown option: $1" 1>&2
- exit 1
- else
- break
+Supported OPTIONS include:
+ --32 Use the 32-bit Android Runtime.
+ --64 Use the 64-bit Android Runtime.
+ --callgrind Launch the Android Runtime in callgrind.
+ -d Use the debug ART library (libartd.so).
+ --debug Equivalent to -d.
+ --gdb Launch the Android Runtime in gdb.
+ --help Display usage message.
+ --invoke-with <program> Launch the Android Runtime in <program>.
+ --perf Launch the Android Runtime with perf recording.
+ --perf-report Launch the Android Runtime with perf recording with
+ report upon completion.
+ --profile Run with profiling, then run using profile data.
+ --verbose Run script verbosely.
+
+The ART_OPTIONS are passed directly to the Android Runtime.
+
+Example:
+ art --32 -cp my_classes.dex MainClass
+
+Common errors:
+ 1) Not having core.art available (see $ANDROID_BUILD_TOP/art/Android.mk).
+ eg m -j32 build-art-host
+ 2) Not having boot.art available (see $ANDROID_BUILD_TOP/build/make/core/dex_preopt_libart_boot.mk)
+ eg m -j32 out/target/product/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art
+EOF
+}
+
+function clean_android_data() {
+ if [ "$DELETE_ANDROID_DATA" = "yes" ]; then
+ rm -rf $ANDROID_DATA
fi
+}
+
+function verbose_run() {
+ if [ "$VERBOSE" = "yes" ]; then
+ echo "$@"
+ fi
+ eval "$@"
+}
+
+function run_art() {
+ verbose_run ANDROID_DATA=$ANDROID_DATA \
+ ANDROID_ROOT=$ANDROID_ROOT \
+ LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
+ PATH=$ANDROID_ROOT/bin:$PATH \
+ LD_USE_LOAD_BIAS=1 \
+ $LAUNCH_WRAPPER $ART_BINARY_PATH $lib \
+ -XXlib:$LIBART \
+ -Xnorelocate \
+ -Ximage:$ANDROID_ROOT/framework/core.art \
+ "$@"
+}
+
+while [[ "$1" = "-"* ]]; do
+ case $1 in
+ --)
+ # No more arguments for this script.
+ shift
+ break
+ ;;
+ --32)
+ ART_BINARY=dalvikvm32
+ ;;
+ --64)
+ ART_BINARY=dalvikvm64
+ ;;
+ --callgrind)
+ LAUNCH_WRAPPER="valgrind --tool=callgrind"
+ ;;
+ -d)
+ ;& # Fallthrough
+ --debug)
+ LIBART="libartd.so"
+ ;;
+ --gdb)
+ LIBART="libartd.so"
+ LAUNCH_WRAPPER="gdb --args"
+ ;;
+ --help)
+ usage
+ exit 0
+ ;;
+ --invoke-with)
+ LAUNCH_WRAPPER=$2
+ shift
+ ;;
+ --perf)
+ PERF="record"
+ ;;
+ --perf-report)
+ PERF="report"
+ ;;
+ --profile)
+ JIT_PROFILE="yes"
+ ;;
+ --verbose)
+ VERBOSE="yes"
+ ;;
+ --*)
+ echo "unknown option: $1" 1>&2
+ usage
+ exit 1
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
done
+if [ $# -eq 0 ]; then
+ usage
+ exit 1
+fi
+
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
ANDROID_ROOT=$PROG_DIR/..
-LIBDIR=$(find_libdir)
-LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR
-DEBUG_OPTION=""
+ART_BINARY_PATH=$ANDROID_ROOT/bin/$ART_BINARY
-DELETE_ANDROID_DATA=false
+if [ ! -x "$ART_BINARY_PATH" ]; then
+ cat 1>&2 <<EOF
+Android Runtime not found: $ART_BINARY_PATH
+This script should be in the same directory as the Android Runtime ($ART_BINARY).
+EOF
+ exit 1
+fi
+
+LIBDIR="$(find_libdir $ART_BINARY_PATH)"
+LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR
+EXTRA_OPTIONS=""
+
# If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own,
# and ensure we delete it at the end.
if [ "$ANDROID_DATA" = "/data" ] || [ "$ANDROID_DATA" = "" ]; then
ANDROID_DATA=$PWD/android-data$$
- mkdir -p $ANDROID_DATA/dalvik-cache/{arm,arm64,x86,x86_64}
- DELETE_ANDROID_DATA=true
+ mkdir -p $ANDROID_DATA/dalvik-cache/$ARCHS
+ DELETE_ANDROID_DATA="yes"
fi
-if [ z"$PERF" != z ]; then
- invoke_with="perf record -g -o $ANDROID_DATA/perf.data -e cycles:u $invoke_with"
- DEBUG_OPTION="-Xcompiler-option --generate-debug-info"
+if [ "$PERF" != "" ]; then
+ LAUNCH_WRAPPER="perf record -g -o $ANDROID_DATA/perf.data -e cycles:u $LAUNCH_WRAPPER"
+ EXTRA_OPTIONS="-Xcompiler-option --generate-debug-info"
fi
-PROFILE_OPTION=""
-EXIT_STATUS=0
-if [ "$JIT_PROFILE" = true ]; then
+if [ "$JIT_PROFILE" = "yes" ]; then
# Create the profile. The runtime expects profiles to be created before
# execution.
PROFILE_PATH="$ANDROID_DATA/primary.prof"
@@ -127,65 +226,51 @@
# Replace the compiler filter with interpret-only so that we
# can capture the profile.
+ ARGS_WITH_INTERPRET_ONLY=
replace_compiler_filter_with_interepret_only "$@"
- ANDROID_DATA=$ANDROID_DATA \
- ANDROID_ROOT=$ANDROID_ROOT \
- LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
- PATH=$ANDROID_ROOT/bin:$PATH \
- LD_USE_LOAD_BIAS=1 \
- $ANDROID_ROOT/bin/$DALVIKVM $lib \
- -XXlib:$LIBART \
- -Xnorelocate \
- -Ximage:$ANDROID_ROOT/framework/core.art \
- -Xjitsaveprofilinginfo \
- -Xps-min-methods-to-save:0 \
- -Xps-min-classes-to-save:0 \
- -Xps-min-notification-before-wake:10 \
- -Xps-profile-path:$PROFILE_PATH \
- -Xusejit:true \
- "${ARGS_WITH_INTERPRET_ONLY[@]}" \
- &> "$ANDROID_DATA/profile_gen.log"
-
+ run_art -Xjitsaveprofilinginfo \
+ -Xps-min-methods-to-save:0 \
+ -Xps-min-classes-to-save:0 \
+ -Xps-min-notification-before-wake:10 \
+ -Xps-profile-path:$PROFILE_PATH \
+ -Xusejit:true \
+ "${ARGS_WITH_INTERPRET_ONLY[@]}" \
+ "&>" "$ANDROID_DATA/profile_gen.log"
EXIT_STATUS=$?
- if [ $EXIT_STATUS = 0 ]; then
- # Wipe dalvik-cache to prepare it for the next invocation.
- rm -rf $ANDROID_DATA/dalvik-cache/{arm,arm64,x86,x86_64}/*
- else
+ if [ $EXIT_STATUS != 0 ]; then
cat "$ANDROID_DATA/profile_gen.log"
+ clean_android_data
+ exit $EXIT_STATUS
fi
- PROFILE_OPTION="-Xcompiler-option --profile-file=$PROFILE_PATH"
+ # Wipe dalvik-cache to prepare it for the next invocation.
+ rm -rf $ANDROID_DATA/dalvik-cache/$ARCHS/*
+
+ # Append arguments so next invocation of run_art uses the profile.
+ EXTRA_OPTIONS="$EXTRA_OPTIONS -Xcompiler-option --profile-file=$PROFILE_PATH"
fi
-# Only run the second invocation if the first one finished successfully.
-if [ $EXIT_STATUS = 0 ]; then
- ANDROID_DATA=$ANDROID_DATA \
- ANDROID_ROOT=$ANDROID_ROOT \
- LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
- PATH=$ANDROID_ROOT/bin:$PATH \
- LD_USE_LOAD_BIAS=1 \
- $invoke_with $ANDROID_ROOT/bin/$DALVIKVM $lib \
- -XXlib:$LIBART \
- -Xnorelocate \
- -Ximage:$ANDROID_ROOT/framework/core.art \
- $DEBUG_OPTION \
- $PROFILE_OPTION \
- "$@"
+# Protect additional arguments in quotes to preserve whitespaces when evaluated.
+# This is for run-jdwp-test.sh which uses this script and has arguments with
+# whitespaces when running on device.
+while [ $# -gt 0 ]; do
+ EXTRA_OPTIONS="$EXTRA_OPTIONS \"$1\""
+ shift
+done
- EXIT_STATUS=$?
-fi
+run_art $EXTRA_OPTIONS
+EXIT_STATUS=$?
-if [ z"$PERF" != z ]; then
- if [ z"$PERF" = zreport ]; then
+if [ "$PERF" != "" ]; then
+ if [ "$PERF" = report ]; then
perf report -i $ANDROID_DATA/perf.data
fi
echo "Perf data saved in: $ANDROID_DATA/perf.data"
else
- if [ "$DELETE_ANDROID_DATA" = "true" ]; then
- rm -rf $ANDROID_DATA
- fi
+ # Perf output is placed under $ANDROID_DATA so not cleaned when perf options used.
+ clean_android_data
fi
exit $EXIT_STATUS