Invoke dex2at before invoking art.
Make sure we always have an oat file before starting dalvikvm.
Checked go/lem and other 'art' users that this CL works for them.
bug: 111174995
bug: 111342996
Test: test.py
Change-Id: Id60760f4185f077ab50df87ce63420dae7bf8aa6
diff --git a/tools/art b/tools/art
index aebf5a6..23eb23b 100644
--- a/tools/art
+++ b/tools/art
@@ -16,28 +16,9 @@
# shell dialect that should work on the host (e.g. bash), and
# Android (e.g. mksh).
-# Globals
-ART_BINARY=dalvikvm
-DELETE_ANDROID_DATA="no"
-LAUNCH_WRAPPER=
-LIBART=libart.so
-JIT_PROFILE="no"
-ALLOW_DEFAULT_JDWP="no"
-VERBOSE="no"
-CLEAN_OAT_FILES="yes"
-EXTRA_OPTIONS=()
-
-# Follow all sym links to get the program name.
-if [ z"$BASH_SOURCE" != z ]; then
- PROG_NAME="$BASH_SOURCE"
-else
- PROG_NAME="$0"
-fi
-while [ -h "$PROG_NAME" ]; do
- # On Mac OS, readlink -f doesn't work.
- PROG_NAME="$(readlink "$PROG_NAME")"
-done
-
+######################################
+# Functions
+######################################
function find_libdir() {
# 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.
@@ -48,29 +29,6 @@
fi
}
-function replace_compiler_filter_with_quicken() {
- ARGS_WITH_QUICKEN=("$@")
-
- found="false"
- ((index=0))
- while ((index <= $#)); do
- what="${ARGS_WITH_QUICKEN[$index]}"
-
- case "$what" in
- --compiler-filter=*)
- ARGS_WITH_QUICKEN[$index]="--compiler-filter=quicken"
- found="true"
- ;;
- esac
-
- ((index++))
- shift
- done
- if [ "$found" != "true" ]; then
- ARGS_WITH_QUICKEN=(-Xcompiler-option --compiler-filter=quicken "${ARGS_WITH_QUICKEN[@]}")
- fi
-}
-
function usage() {
cat 1>&2 <<EOF
Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS
@@ -224,19 +182,78 @@
echo "$image_location"
}
-# If android logging is not explicitly set, only print warnings and errors.
-if [ -z "$ANDROID_LOG_TAGS" ]; then
- ANDROID_LOG_TAGS='*:w'
-fi
+function run_dex2oat() {
+ CLASS_LOADER_CONTEXT=
+ for dex_file in "${DEX2OAT_CLASSPATH[@]}"
+ do
+ while [ -h "$dex_file" ]; do
+ # On Mac OS, readlink -f doesn't work.
+ dex_file="$(readlink "$dex_file")"
+ done
+ # Create oat file directory.
+ verbose_run mkdir -p $(dirname "$dex_file")/oat/$ISA
+ local oat_file=$(basename "$dex_file")
+ local oat_file=$(dirname "$dex_file")/oat/$ISA/${oat_file%.*}.odex
+ # When running dex2oat use the exact same context as when running dalvikvm.
+ # (see run_art function)
+ 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 \
+ ANDROID_LOG_TAGS=$ANDROID_LOG_TAGS \
+ $DEX2OAT_BINARY_PATH \
+ --runtime-arg -Xnorelocate \
+ --boot-image=$DEX2OAT_BOOT_IMAGE \
+ --instruction-set=$ISA \
+ --class-loader-context="PCL[$CLASS_LOADER_CONTEXT]" \
+ "${DEX2OAT_FLAGS[@]}" \
+ --dex-file=$dex_file \
+ --oat-file=$oat_file
+ if [[ ! -z $CLASS_LOADER_CONTEXT ]]; then
+ CLASS_LOADER_CONTEXT+=":"
+ fi
+ CLASS_LOADER_CONTEXT+="$dex_file"
+ done
+}
+
+# Extract the dex2oat flags from the list of arguments.
+# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array
+# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH
+# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE
+function extract_dex2oat_flags() {
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -Xcompiler-option)
+ DEX2OAT_FLAGS+=("$2")
+ shift
+ ;;
+ -Ximage:*)
+ DEX2OAT_BOOTIMAGE=$1
+ # Remove '-Ximage:' from the argument.
+ DEX2OAT_BOOT_IMAGE=${DEX2OAT_BOOT_IMAGE##-Ximage:}
+ ;;
+ -cp)
+ # TODO: support -classpath and CLASSPATH
+ local oifs=$IFS
+ IFS=':'
+ for classpath_elem in $2
+ do
+ DEX2OAT_CLASSPATH+=("$classpath_elem")
+ done
+ shift
+ IFS=$oifs
+ ;;
+ esac
+ shift
+ done
+}
# Runs dalvikvm, returns its exit code.
# (Oat directories are cleaned up in between runs)
function run_art() {
- local image_location="$(detect_boot_image_location)"
local ret
- # First cleanup any left-over 'oat' files from the last time dalvikvm was run.
- cleanup_oat_directory_for_classpath "$@"
# Run dalvikvm.
verbose_run ANDROID_DATA="$ANDROID_DATA" \
ANDROID_ROOT="$ANDROID_ROOT" \
@@ -247,7 +264,7 @@
$LAUNCH_WRAPPER $ART_BINARY_PATH $lib \
-XXlib:"$LIBART" \
-Xnorelocate \
- -Ximage:"$image_location" \
+ -Ximage:"$DEFAULT_IMAGE_LOCATION" \
"$@"
ret=$?
@@ -258,6 +275,23 @@
return $ret
}
+######################################
+# Globals
+######################################
+ART_BINARY=dalvikvm
+DEX2OAT_BINARY=dex2oat
+DELETE_ANDROID_DATA="no"
+LAUNCH_WRAPPER=
+LIBART=libart.so
+JIT_PROFILE="no"
+ALLOW_DEFAULT_JDWP="no"
+VERBOSE="no"
+CLEAN_OAT_FILES="yes"
+EXTRA_OPTIONS=()
+DEX2OAT_FLAGS=()
+DEX2OAT_CLASSPATH=()
+
+# Parse arguments
while [[ "$1" = "-"* ]]; do
case "$1" in
--)
@@ -275,6 +309,7 @@
;& # Fallthrough
--debug)
LIBART="libartd.so"
+ DEX2OAT_BINARY=dex2oatd
# Expect that debug mode wants all checks.
EXTRA_OPTIONS+=(-XX:SlowDebug=true)
;;
@@ -329,9 +364,21 @@
exit 1
fi
+# Follow all sym links to get the program name.
+if [ z"$BASH_SOURCE" != z ]; then
+ PROG_NAME="$BASH_SOURCE"
+else
+ PROG_NAME="$0"
+fi
+while [ -h "$PROG_NAME" ]; do
+ # On Mac OS, readlink -f doesn't work.
+ PROG_NAME="$(readlink "$PROG_NAME")"
+done
+
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
ANDROID_ROOT=$PROG_DIR/..
ART_BINARY_PATH=$ANDROID_ROOT/bin/$ART_BINARY
+ISA=$($ART_BINARY_PATH -showversion | (read art version number isa && echo $isa))
if [ ! -x "$ART_BINARY_PATH" ]; then
cat 1>&2 <<EOF
@@ -341,8 +388,31 @@
exit 1
fi
+DEX2OAT_BINARY_PATH=$ANDROID_ROOT/bin/$DEX2OAT_BINARY
+
+if [ ! -x "$DEX2OAT_BINARY_PATH" ]; then
+ echo "Warning: Android Compiler not found: $DEX2OAT_BINARY_PATH"
+fi
+
+######################################
+# Main program
+######################################
+
+# If android logging is not explicitly set, only print warnings and errors.
+if [ -z "$ANDROID_LOG_TAGS" ]; then
+ ANDROID_LOG_TAGS='*:w'
+fi
+
LIBDIR="$(find_libdir $ART_BINARY_PATH)"
LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR
+DEFAULT_IMAGE_LOCATION="$(detect_boot_image_location)"
+DEX2OAT_BOOT_IMAGE="$DEFAULT_IMAGE_LOCATION"
+
+# Extract the dex2oat flags from the list of arguments.
+# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array
+# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH
+# -Ximage argument is stored in DEX2OAT_BOOTIMAGE
+extract_dex2oat_flags "$@"
# If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own,
# and ensure we delete it at the end.
@@ -360,31 +430,34 @@
if [ "$PERF" != "" ]; then
LAUNCH_WRAPPER="perf record -g --call-graph dwarf -F 10000 -o $ANDROID_DATA/perf.data -e cycles:u $LAUNCH_WRAPPER"
- EXTRA_OPTIONS+=(-Xcompiler-option --generate-debug-info)
+ DEX2OAT_FLAGS+=(--generate-debug-info)
fi
if [ "$ALLOW_DEFAULT_JDWP" = "no" ]; then
EXTRA_OPTIONS+=(-XjdwpProvider:none)
fi
+# First cleanup any left-over 'oat' files from the last time dalvikvm was run.
+cleanup_oat_directory_for_classpath "$@"
+
+# Protect additional arguments in quotes to preserve whitespaces (used by
+# run-jdwp-test.sh when running on device), '$' (may be used as part of
+# classpath) and other special characters when evaluated.
+EXTRA_OPTIONS+=("$@")
+
if [ "$JIT_PROFILE" = "yes" ]; then
# Create the profile. The runtime expects profiles to be created before
# execution.
PROFILE_PATH="$ANDROID_DATA/primary.prof"
touch "$PROFILE_PATH"
- # Replace the compiler filter with quicken so that we
- # can capture the profile.
- ARGS_WITH_QUICKEN=
- replace_compiler_filter_with_quicken "$@"
-
run_art -Xjitsaveprofilinginfo \
-Xps-min-methods-to-save:1 \
-Xps-min-classes-to-save:1 \
-Xps-min-notification-before-wake:10 \
-Xps-profile-path:$PROFILE_PATH \
-Xusejit:true \
- "${ARGS_WITH_QUICKEN[@]}" \
+ ${EXTRA_OPTIONS[@]} \
&> "$ANDROID_DATA/profile_gen.log"
EXIT_STATUS=$?
@@ -400,13 +473,20 @@
rm -rf "$ANDROID_DATA/dalvik-cache"
# Append arguments so next invocation of run_art uses the profile.
- EXTRA_OPTIONS+=(-Xcompiler-option --profile-file="$PROFILE_PATH")
+ DEX2OAT_FLAGS+=(--profile-file="$PROFILE_PATH")
fi
-# Protect additional arguments in quotes to preserve whitespaces (used by
-# run-jdwp-test.sh when running on device), '$' (may be used as part of
-# classpath) and other special characters when evaluated.
-EXTRA_OPTIONS+=("$@")
+if [ -x "$DEX2OAT_BINARY_PATH" ]; then
+ # Run dex2oat before launching ART to generate the oat files for the classpath.
+ run_dex2oat
+fi
+
+# Do not continue if the dex2oat failed.
+EXIT_STATUS=$?
+if [ $EXIT_STATUS != 0 ]; then
+ echo "Failed dex2oat invocation" >&2
+ exit $EXIT_STATUS
+fi
run_art "${EXTRA_OPTIONS[@]}"
EXIT_STATUS=$?