1 # Copyright (C) 2011 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 # This script is used on host and device. It uses a common subset 16 # shell dialect that should work on the host (e.g. bash), and 17 # Android (e.g. mksh). 18 19 # Globals 20 ARCHS={arm,arm64,mips,mips64,x86,x86_64} 21 ART_BINARY=dalvikvm 22 DELETE_ANDROID_DATA="no" 23 LAUNCH_WRAPPER= 24 LIBART=libart.so 25 JIT_PROFILE="no" 26 VERBOSE="no" 27 28 # Follow all sym links to get the program name. 29 if [ z"$BASH_SOURCE" != z ]; then 30 PROG_NAME="$BASH_SOURCE" 31 else 32 PROG_NAME="$0" 33 fi 34 while [ -h "$PROG_NAME" ]; do 35 # On Mac OS, readlink -f doesn't work. 36 PROG_NAME="$(readlink "$PROG_NAME")" 37 done 38 39 function find_libdir() { 40 # Get the actual file, $1 is the ART_BINARY_PATH and may be a symbolic link. 41 # Use realpath instead of readlink because Android does not have a readlink. 42 if [[ "$(realpath "$1")" == *dalvikvm64 ]]; then 43 echo "lib64" 44 else 45 echo "lib" 46 fi 47 } 48 49 function replace_compiler_filter_with_quicken() { 50 ARGS_WITH_QUICKEN=("$@") 51 52 found="false" 53 ((index=0)) 54 while ((index <= $#)); do 55 what="${ARGS_WITH_QUICKEN[$index]}" 56 57 case "$what" in 58 --compiler-filter=*) 59 ARGS_WITH_QUICKEN[$index]="--compiler-filter=quicken" 60 found="true" 61 ;; 62 esac 63 64 ((index++)) 65 shift 66 done 67 if [ "$found" != "true" ]; then 68 ARGS_WITH_QUICKEN=(-Xcompiler-option --compiler-filter=quicken "${ARGS_WITH_QUICKEN[@]}") 69 fi 70 } 71 72 function usage() { 73 cat 1>&2 <<EOF 74 Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS 75 76 Supported OPTIONS include: 77 --32 Use the 32-bit Android Runtime. 78 --64 Use the 64-bit Android Runtime. 79 --callgrind Launch the Android Runtime in callgrind. 80 -d Use the debug ART library (libartd.so). 81 --debug Equivalent to -d. 82 --gdb Launch the Android Runtime in gdb. 83 --help Display usage message. 84 --invoke-with <program> Launch the Android Runtime in <program>. 85 --perf Launch the Android Runtime with perf recording. 86 --perf-report Launch the Android Runtime with perf recording with 87 report upon completion. 88 --profile Run with profiling, then run using profile data. 89 --verbose Run script verbosely. 90 91 The ART_OPTIONS are passed directly to the Android Runtime. 92 93 Example: 94 art --32 -cp my_classes.dex MainClass 95 96 Common errors: 97 1) Not having core.art available (see $ANDROID_BUILD_TOP/art/Android.mk). 98 eg m -j32 build-art-host 99 2) Not having boot.art available (see $ANDROID_BUILD_TOP/build/make/core/dex_preopt_libart_boot.mk) 100 eg m -j32 out/target/product/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art 101 EOF 102 } 103 104 function clean_android_data() { 105 if [ "$DELETE_ANDROID_DATA" = "yes" ]; then 106 rm -rf $ANDROID_DATA 107 fi 108 } 109 110 function verbose_run() { 111 if [ "$VERBOSE" = "yes" ]; then 112 echo "$@" 113 fi 114 eval "$@" 115 } 116 117 function run_art() { 118 verbose_run ANDROID_DATA=$ANDROID_DATA \ 119 ANDROID_ROOT=$ANDROID_ROOT \ 120 LD_LIBRARY_PATH=$LD_LIBRARY_PATH \ 121 PATH=$ANDROID_ROOT/bin:$PATH \ 122 LD_USE_LOAD_BIAS=1 \ 123 $LAUNCH_WRAPPER $ART_BINARY_PATH $lib \ 124 -XXlib:$LIBART \ 125 -Xnorelocate \ 126 -Ximage:$ANDROID_ROOT/framework/core.art \ 127 "$@" 128 } 129 130 while [[ "$1" = "-"* ]]; do 131 case $1 in 132 --) 133 # No more arguments for this script. 134 shift 135 break 136 ;; 137 --32) 138 ART_BINARY=dalvikvm32 139 ;; 140 --64) 141 ART_BINARY=dalvikvm64 142 ;; 143 --callgrind) 144 LAUNCH_WRAPPER="valgrind --tool=callgrind" 145 ;; 146 -d) 147 ;& # Fallthrough 148 --debug) 149 LIBART="libartd.so" 150 ;; 151 --gdb) 152 LIBART="libartd.so" 153 LAUNCH_WRAPPER="gdb --args" 154 ;; 155 --help) 156 usage 157 exit 0 158 ;; 159 --invoke-with) 160 LAUNCH_WRAPPER=$2 161 shift 162 ;; 163 --perf) 164 PERF="record" 165 ;; 166 --perf-report) 167 PERF="report" 168 ;; 169 --profile) 170 JIT_PROFILE="yes" 171 ;; 172 --verbose) 173 VERBOSE="yes" 174 ;; 175 --*) 176 echo "unknown option: $1" 1>&2 177 usage 178 exit 1 179 ;; 180 *) 181 break 182 ;; 183 esac 184 shift 185 done 186 187 if [ $# -eq 0 ]; then 188 usage 189 exit 1 190 fi 191 192 PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" 193 ANDROID_ROOT=$PROG_DIR/.. 194 ART_BINARY_PATH=$ANDROID_ROOT/bin/$ART_BINARY 195 196 if [ ! -x "$ART_BINARY_PATH" ]; then 197 cat 1>&2 <<EOF 198 Android Runtime not found: $ART_BINARY_PATH 199 This script should be in the same directory as the Android Runtime ($ART_BINARY). 200 EOF 201 exit 1 202 fi 203 204 LIBDIR="$(find_libdir $ART_BINARY_PATH)" 205 LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR 206 EXTRA_OPTIONS="" 207 208 # If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own, 209 # and ensure we delete it at the end. 210 if [ "$ANDROID_DATA" = "/data" ] || [ "$ANDROID_DATA" = "" ]; then 211 ANDROID_DATA=$PWD/android-data$$ 212 mkdir -p $ANDROID_DATA/dalvik-cache/$ARCHS 213 DELETE_ANDROID_DATA="yes" 214 fi 215 216 if [ "$PERF" != "" ]; then 217 LAUNCH_WRAPPER="perf record -g -o $ANDROID_DATA/perf.data -e cycles:u $LAUNCH_WRAPPER" 218 EXTRA_OPTIONS="-Xcompiler-option --generate-debug-info" 219 fi 220 221 if [ "$JIT_PROFILE" = "yes" ]; then 222 # Create the profile. The runtime expects profiles to be created before 223 # execution. 224 PROFILE_PATH="$ANDROID_DATA/primary.prof" 225 touch $PROFILE_PATH 226 227 # Replace the compiler filter with quicken so that we 228 # can capture the profile. 229 ARGS_WITH_QUICKEN= 230 replace_compiler_filter_with_quicken "$@" 231 232 run_art -Xjitsaveprofilinginfo \ 233 -Xps-min-methods-to-save:1 \ 234 -Xps-min-classes-to-save:1 \ 235 -Xps-min-notification-before-wake:10 \ 236 -Xps-profile-path:$PROFILE_PATH \ 237 -Xusejit:true \ 238 "${ARGS_WITH_QUICKEN[@]}" \ 239 "&>" "$ANDROID_DATA/profile_gen.log" 240 EXIT_STATUS=$? 241 242 if [ $EXIT_STATUS != 0 ]; then 243 cat "$ANDROID_DATA/profile_gen.log" 244 clean_android_data 245 exit $EXIT_STATUS 246 fi 247 248 # Wipe dalvik-cache to prepare it for the next invocation. 249 rm -rf $ANDROID_DATA/dalvik-cache/$ARCHS/* 250 251 # Append arguments so next invocation of run_art uses the profile. 252 EXTRA_OPTIONS="$EXTRA_OPTIONS -Xcompiler-option --profile-file=$PROFILE_PATH" 253 fi 254 255 # Protect additional arguments in quotes to preserve whitespaces when evaluated. 256 # This is for run-jdwp-test.sh which uses this script and has arguments with 257 # whitespaces when running on device. 258 while [ $# -gt 0 ]; do 259 EXTRA_OPTIONS="$EXTRA_OPTIONS \"$1\"" 260 shift 261 done 262 263 run_art $EXTRA_OPTIONS 264 EXIT_STATUS=$? 265 266 if [ "$PERF" != "" ]; then 267 if [ "$PERF" = report ]; then 268 perf report -i $ANDROID_DATA/perf.data 269 fi 270 echo "Perf data saved in: $ANDROID_DATA/perf.data" 271 else 272 # Perf output is placed under $ANDROID_DATA so not cleaned when perf options used. 273 clean_android_data 274 fi 275 276 exit $EXIT_STATUS 277