Add --profile mode to the art script
--profile will run dalvikmvm twice. The first run records the profile by
replacing the compiler filter with interpret-only and enabling profile
saving. The second run will pass the recorded profile to dex2oat using
'-Xcompiler-option --profile-file=...'.
Test: ./out/host/linux-x86/bin/art --profile --64 -Ximage:$PWD/out/host/linux-x86/framework/core.art -Xusejit:true -Xcompiler-option --compiler-filter=speed -Xcompiler-option --compiler-backend=Optimizing -verbose:oat -Djava.library.path=$PWD/out/x86_64/host/linux-x86/lib64 -cp $PWD/generated/benchmarks.dex benchmarks.ExoPlayerBench.java.ExoPlayerBench
Bug: 36032648
Change-Id: I2dbcae43dd2972273511df9e01ebcbdfb1d84372
diff --git a/tools/art b/tools/art
index 91d6e27..f5e0860 100644
--- a/tools/art
+++ b/tools/art
@@ -16,18 +16,16 @@
# shell dialect that should work on the host (e.g. bash), and
# Android (e.g. mksh).
-function follow_links() {
- if [ z"$BASH_SOURCE" != z ]; then
- file="$BASH_SOURCE"
- else
- file="$0"
- fi
- while [ -h "$file" ]; do
- # On Mac OS, readlink -f doesn't work.
- file="$(readlink "$file")"
- done
- echo "$file"
-}
+# 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
function find_libdir() {
# Get the actual file, $DALVIKVM may be a symbolic link.
@@ -39,9 +37,34 @@
fi
}
+ARGS_WITH_INTERPRET_ONLY=
+function replace_compiler_filter_with_interepret_only() {
+ ARGS_WITH_INTERPRET_ONLY=("$@")
+
+ found="false"
+ ((index=0))
+ while ((index <= $#)); do
+ what="${ARGS_WITH_INTERPRET_ONLY[$index]}"
+
+ case "$what" in
+ --compiler-filter=*)
+ ARGS_WITH_INTERPRET_ONLY[$index]="--compiler-filter=interpret-only"
+ found="true"
+ ;;
+ esac
+
+ ((index++))
+ shift
+ done
+ if [ "$found" != "true" ]; then
+ ARGS_WITH_INTERPRET_ONLY=(-Xcompiler-option --compiler-filter=interpret-only "${ARGS_WITH_INTERPRET_ONLY[@]}")
+ fi
+}
+
invoke_with=
DALVIKVM=dalvikvm
LIBART=libart.so
+JIT_PROFILE=false
while true; do
if [ "$1" = "--invoke-with" ]; then
@@ -63,6 +86,9 @@
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
@@ -71,7 +97,6 @@
fi
done
-PROG_NAME="$(follow_links)"
PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
ANDROID_ROOT=$PROG_DIR/..
LIBDIR=$(find_libdir)
@@ -92,20 +117,65 @@
DEBUG_OPTION="-Xcompiler-option --generate-debug-info"
fi
-# We use the PIC core image to work with perf.
-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=""
+EXIT_STATUS=0
+if [ "$JIT_PROFILE" = true ]; then
+ # Create the profile. The runtime expects profiles to be created before
+ # execution.
+ PROFILE_PATH="$ANDROID_DATA/primary.prof"
+ touch $PROFILE_PATH
-EXIT_STATUS=$?
+ # Replace the compiler filter with interpret-only so that we
+ # can capture the profile.
+ 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"
+
+ 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
+ cat "$ANDROID_DATA/profile_gen.log"
+ fi
+
+ PROFILE_OPTION="-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 \
+ "$@"
+
+ EXIT_STATUS=$?
+fi
if [ z"$PERF" != z ]; then
if [ z"$PERF" = zreport ]; then