1#! /bin/sh 2# Copyright (C) 2011 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16# This script is used on host and device. It uses a common subset 17# shell dialect that should work on the host (e.g. bash), and 18# Android (e.g. mksh). Try to switch to bash if the shebang above 19# has launched a pessimal shell on host. 20if [ -z "$KSH_VERSION" -a -z "$BASH_VERSION" -a -n "$(which bash)" ]; then 21 exec bash -c ". $0" -- "$@" 22fi 23 24###################################### 25# Functions 26###################################### 27function find_libdir() { 28 # Get the actual file, $1 is the ART_BINARY_PATH and may be a symbolic link. 29 # Use realpath instead of readlink because Android does not have a readlink. 30 if [[ "$(realpath "$1")" == *dalvikvm64 ]]; then 31 echo "lib64" 32 else 33 echo "lib" 34 fi 35} 36 37function usage() { 38 cat 1>&2 <<EOF 39Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS 40 41Supported OPTIONS include: 42 --32 Use the 32-bit Android Runtime. 43 --64 Use the 64-bit Android Runtime. 44 -d Use the debug ART library (libartd.so). 45 --debug Equivalent to -d. 46 --gdb Launch the Android Runtime in gdb. 47 --gdbserver <comms> Launch the Android Runtime in gdbserver using the 48 supplied communication channel. 49 --help Display usage message. 50 --invoke-with <program> Launch the Android Runtime in <program>. 51 --perf Launch the Android Runtime with perf recording. 52 --perf-report Launch the Android Runtime with perf recording with 53 report upon completion. 54 --profile Run with profiling, then run using profile data. 55 --verbose Run script verbosely. 56 --no-clean Don't cleanup oat directories. 57 --no-compile Don't invoke dex2oat before running. 58 --allow-default-jdwp Don't automatically put in -XjdwpProvider:none. 59 You probably do not want this. 60 61The ART_OPTIONS are passed directly to the Android Runtime. 62 63Example: 64 art --32 -cp my_classes.dex MainClass 65 66Common errors: 67 1) Not having core.art available (see $ANDROID_BUILD_TOP/art/Android.mk). 68 eg m -j32 build-art-host 69 2) Not having boot.art available (see $ANDROID_BUILD_TOP/build/make/core/dex_preopt_libart_boot.mk) 70 eg m -j32 out/target/product/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art 71EOF 72} 73 74function clean_android_data() { 75 if [ "$DELETE_ANDROID_DATA" = "yes" ]; then 76 rm -rf $ANDROID_DATA 77 fi 78} 79 80# Given 'VAR1=VAL VAR2=VAL2 ... cmd arg1 arg2 ... argN' run the 'cmd' with the args 81# with the modified environment {VAR1=VAL,VAL2=,...}. 82# 83# Also prints the command to be run if verbose mode is enabled. 84function verbose_run() { 85 if [ "$VERBOSE" = "yes" ]; then 86 echo "$@" 87 fi 88 89 env "$@" 90} 91 92# Parse a colon-separated list into an array (e.g. "foo.dex:bar.dex" -> (foo.dex bar.dex)) 93PARSE_CLASSPATH_RESULT=() # Return value will be here due to shell limitations. 94parse_classpath() { 95 local cp="$1" 96 local oldifs=$IFS 97 98 local cp_array 99 cp_array=() 100 101 IFS=":" 102 for part in $cp; do 103 cp_array+=("$part") 104 done 105 IFS=$oldifs 106 107 PARSE_CLASSPATH_RESULT=("${cp_array[@]}") 108} 109 110# Sets 'PARSE_CLASSPATH_RESULT' to an array of class path dex files. 111# e.g. (-cp foo/classes.dex:bar/classes.dex) -> (foo/classes.dex bar/classes.dex) 112find_cp_in_args() { 113 local found="false" 114 local index=0 115 local what 116 117 while [[ $# -gt 0 ]]; do 118 case "$1" in 119 -cp|-classpath) 120 parse_classpath "$2" 121 # Sets 'PARSE_CLASSPATH_RESULT' to an array of class path dex files. 122 # Subsequent parses will overwrite the preceding. 123 shift 124 ;; 125 esac 126 shift 127 done 128} 129 130# Delete the 'oat' directories relative to the classpath's dex files. 131# e.g. (foo/classes.dex bar/classes.dex) would delete (foo/oat bar/oat) directories. 132cleanup_oat_directory() { 133 local classpath 134 classpath=("$@") 135 136 local dirpath 137 138 for path in "${classpath[@]}"; do 139 dirpath="$(dirname "$path")" 140 [[ -d "$dirpath" ]] && verbose_run rm -rf "$dirpath/oat" 141 done 142} 143 144# Parse -cp <CP>, -classpath <CP>, and $CLASSPATH to find the dex files. 145# Each dex file's directory will have an 'oat' file directory, delete it. 146# Input: Command line arguments to the art script. 147# e.g. -cp foo/classes.dex:bar/classes.dex would delete (foo/oat bar/oat) directories. 148cleanup_oat_directory_for_classpath() { 149 if [ "$CLEAN_OAT_FILES" = "yes" ]; then 150 # First try: Use $CLASSPATH environment variable. 151 parse_classpath "$CLASSPATH" 152 # Second try: Look for latest -cp or -classpath arg which will take precedence. 153 find_cp_in_args "$@" 154 155 cleanup_oat_directory "${PARSE_CLASSPATH_RESULT[@]}" 156 fi 157} 158 159# Attempt to find $ANDROID_ROOT/framework/<isa>/core.art' without knowing what <isa> is. 160function check_if_boot_image_file_exists() { 161 local image_location_dir="$1" 162 local image_location_name="$2" 163 164 # Expand image_files to a list of existing image files on the disk. 165 # If no such files exist, it expands to single element 'dir/*/file' with a literal '*'. 166 local image_files 167 image_files=("$image_location_dir"/*/"$image_location_name") # avoid treating "*" as literal. 168 169 # Array always has at least 1 element. Test explicitly whether the file exists. 170 [[ -e "${image_files[0]}" ]] 171} 172 173# Automatically find the boot image location. It uses core.art by default. 174# On a real device, it might only have a boot.art, so use that instead when core.art does not exist. 175function detect_boot_image_location() { 176 local image_location_dir="$ANDROID_ROOT/framework" 177 local image_location_name="core.art" 178 179 # If there are no existing core.art, try to find boot.art. 180 # If there is no boot.art then leave it as-is, assumes -Ximage is explicitly used. 181 # Otherwise let dalvikvm give the error message about an invalid image file. 182 if ! check_if_boot_image_file_exists "$image_location_dir" "core.art" && \ 183 check_if_boot_image_file_exists "$image_location_dir" "boot.art"; then 184 image_location_name="boot.art" 185 fi 186 187 local image_location="$image_location_dir/$image_location_name" 188 echo "$image_location" 189} 190 191function run_dex2oat() { 192 local class_loader_context= 193 for dex_file in "${DEX2OAT_CLASSPATH[@]}" 194 do 195 while [ -h "$dex_file" ]; do 196 # On Mac OS, readlink -f doesn't work. 197 dex_file="$(readlink "$dex_file")" 198 done 199 # Create oat file directory. 200 verbose_run mkdir -p $(dirname "$dex_file")/oat/$ISA 201 local oat_file=$(basename "$dex_file") 202 local oat_file=$(dirname "$dex_file")/oat/$ISA/${oat_file%.*}.odex 203 if [ "$GENERATE_APP_IMAGE" = "yes" ]; then 204 local art_file=$(basename "$dex_file") 205 local art_file=$(dirname "$dex_file")/oat/$ISA/${art_file%.*}.art 206 DEX2OAT_FLAGS+=("--app-image-file=$art_file") 207 fi 208 209 # When running dex2oat use the exact same context as when running dalvikvm. 210 # (see run_art function) 211 verbose_run ANDROID_DATA=$ANDROID_DATA \ 212 ANDROID_ROOT=$ANDROID_ROOT \ 213 ANDROID_I18N_ROOT=$ANDROID_I18N_ROOT \ 214 ANDROID_ART_ROOT=$ANDROID_ART_ROOT \ 215 ANDROID_TZDATA_ROOT=$ANDROID_TZDATA_ROOT \ 216 LD_LIBRARY_PATH=$LD_LIBRARY_PATH \ 217 PATH=$ANDROID_ROOT/bin:$PATH \ 218 LD_USE_LOAD_BIAS=1 \ 219 ANDROID_LOG_TAGS=$ANDROID_LOG_TAGS \ 220 $DEX2OAT_BINARY_PATH \ 221 --runtime-arg -Xnorelocate \ 222 --boot-image=$DEX2OAT_BOOT_IMAGE \ 223 --instruction-set=$ISA \ 224 --class-loader-context="PCL[$class_loader_context]" \ 225 "${DEX2OAT_FLAGS[@]}" \ 226 --dex-file=$dex_file \ 227 --oat-file=$oat_file 228 if [[ -n $class_loader_context ]]; then 229 class_loader_context+=":" 230 fi 231 class_loader_context+="$dex_file" 232 done 233} 234 235# Extract the dex2oat flags from the list of arguments. 236# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array 237# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH 238# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE 239# -Xbootclasspath argument is stored in DEX2OAT_BCP 240# -Xbootclasspath-locations argument is stored in DEX2OAT_BCP_LOCS 241function extract_dex2oat_flags() { 242 while [ $# -gt 0 ]; do 243 case $1 in 244 -Xcompiler-option) 245 DEX2OAT_FLAGS+=("$2") 246 247 # Enable app images for profile filters 248 case $2 in 249 --compiler-filter=speed-profile) 250 GENERATE_APP_IMAGE="yes" 251 ;; 252 --compiler-filter=everything-profile) 253 GENERATE_APP_IMAGE="yes" 254 ;; 255 esac 256 257 shift 258 ;; 259 -Ximage:*) 260 DEX2OAT_BOOT_IMAGE=$1 261 # Remove '-Ximage:' from the argument. 262 DEX2OAT_BOOT_IMAGE=${DEX2OAT_BOOT_IMAGE##-Ximage:} 263 ;; 264 -Xbootclasspath:*) 265 DEX2OAT_BCP=$1 266 # Remove '-Xbootclasspath:' from the argument. 267 DEX2OAT_BCP=${DEX2OAT_BCP##-Xbootclasspath:} 268 ;; 269 -Xbootclasspath-locations:*) 270 DEX2OAT_BCP_LOCS=$1 271 # Remove '-Xbootclasspath-locations:' from the argument. 272 DEX2OAT_BCP_LOCS=${DEX2OAT_BCP_LOCS##-Xbootclasspath-locations:} 273 ;; 274 -cp) 275 # Reset any previously parsed classpath, just like dalvikvm 276 # only supports one -cp argument. 277 DEX2OAT_CLASSPATH=() 278 # TODO: support -classpath and CLASSPATH 279 local oifs=$IFS 280 IFS=':' 281 for classpath_elem in $2 282 do 283 DEX2OAT_CLASSPATH+=("$classpath_elem") 284 done 285 shift 286 IFS=$oifs 287 ;; 288 esac 289 shift 290 done 291} 292 293# Runs dalvikvm, returns its exit code. 294# (Oat directories are cleaned up in between runs) 295function run_art() { 296 local ret 297 298 # Run dalvikvm. 299 verbose_run ANDROID_DATA="$ANDROID_DATA" \ 300 ANDROID_ROOT="$ANDROID_ROOT" \ 301 ANDROID_I18N_ROOT="$ANDROID_I18N_ROOT" \ 302 ANDROID_ART_ROOT="$ANDROID_ART_ROOT" \ 303 ANDROID_TZDATA_ROOT="$ANDROID_TZDATA_ROOT" \ 304 LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \ 305 PATH="$ANDROID_ROOT/bin:$PATH" \ 306 LD_USE_LOAD_BIAS=1 \ 307 ANDROID_LOG_TAGS="$ANDROID_LOG_TAGS" \ 308 $LAUNCH_WRAPPER $ART_BINARY_PATH $lib \ 309 -XXlib:"$LIBART" \ 310 -Xnorelocate \ 311 -Ximage:"$DEFAULT_IMAGE_LOCATION" \ 312 "$@" 313 ret=$? 314 315 # Avoid polluting disk with 'oat' files after dalvikvm has finished. 316 cleanup_oat_directory_for_classpath "$@" 317 318 # Forward exit code of dalvikvm. 319 return $ret 320} 321 322###################################### 323# Globals 324###################################### 325ART_BINARY=dalvikvm 326DEX2OAT_BINARY=dex2oat 327DEX2OAT_SUFFIX="" 328DELETE_ANDROID_DATA="no" 329LAUNCH_WRAPPER= 330LIBART=libart.so 331JIT_PROFILE="no" 332ALLOW_DEFAULT_JDWP="no" 333VERBOSE="no" 334CLEAN_OAT_FILES="yes" 335RUN_DEX2OAT="yes" 336EXTRA_OPTIONS=() 337DEX2OAT_FLAGS=() 338DEX2OAT_CLASSPATH=() 339GENERATE_APP_IMAGE="no" 340 341# Parse arguments 342while [[ "$1" = "-"* ]]; do 343 case "$1" in 344 --) 345 # No more arguments for this script. 346 shift 347 break 348 ;; 349 --32) 350 ART_BINARY=dalvikvm32 351 DEX2OAT_SUFFIX=32 352 ;; 353 --64) 354 ART_BINARY=dalvikvm64 355 DEX2OAT_SUFFIX=64 356 ;; 357 -d) 358 ;& # Fallthrough 359 --debug) 360 LIBART="libartd.so" 361 DEX2OAT_BINARY="dex2oatd" 362 # Expect that debug mode wants all checks. 363 EXTRA_OPTIONS+=(-XX:SlowDebug=true) 364 ;; 365 --gdbserver) 366 LAUNCH_WRAPPER="gdbserver $2" 367 shift 368 ;; 369 --gdb) 370 LIBART="libartd.so" 371 LAUNCH_WRAPPER="gdb --args" 372 ;; 373 --help) 374 usage 375 exit 0 376 ;; 377 --invoke-with) 378 LAUNCH_WRAPPER=$2 379 shift 380 ;; 381 --perf) 382 PERF="record" 383 ;; 384 --perf-report) 385 PERF="report" 386 ;; 387 --profile) 388 JIT_PROFILE="yes" 389 ;; 390 --verbose) 391 VERBOSE="yes" 392 ;; 393 --no-clean) 394 CLEAN_OAT_FILES="no" 395 ;; 396 --no-compile) 397 CLEAN_OAT_FILES="no" 398 RUN_DEX2OAT="no" 399 ;; 400 --allow-default-jdwp) 401 ALLOW_DEFAULT_JDWP="yes" 402 ;; 403 --*) 404 echo "unknown option: $1" 1>&2 405 usage 406 exit 1 407 ;; 408 *) 409 break 410 ;; 411 esac 412 shift 413done 414 415if [ $# -eq 0 ]; then 416 usage 417 exit 1 418fi 419 420# Follow all sym links to get the program name. 421if [[ -n "$BASH_SOURCE" ]]; then 422 PROG_NAME="$BASH_SOURCE" 423else 424 PROG_NAME="$0" 425fi 426while [ -h "$PROG_NAME" ]; do 427 # On Mac OS, readlink -f doesn't work. 428 PROG_NAME="$(readlink "$PROG_NAME")" 429done 430 431PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)" 432ANDROID_ROOT="$(cd $PROG_DIR/..; pwd -P)" 433 434# If ANDROID_I18N_ROOT is not set, try to detect whether we are running on 435# target or host and set that environment variable to the usual default value. 436if [ -z "$ANDROID_I18N_ROOT" ]; then 437 # This script is used on host and target (device). However, the (expected) 438 # default value `ANDROID_I18N_ROOT` is not the same on host and target: 439 # - on host, `ANDROID_I18N_ROOT` is expected to be 440 # "$ANDROID_ROOT/com.android.i18n"; 441 # - on target, `ANDROID_I18N_ROOT` is expected to be 442 # "/apex/com.android.i18n". 443 # 444 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to 445 # determine whether we are on target or host (this is brittle, but simple). 446 if [ -d "$ANDROID_ROOT/../apex" ]; then 447 # Target case. 448 ANDROID_I18N_ROOT="/apex/com.android.i18n" 449 else 450 # Host case. 451 ANDROID_I18N_ROOT="$ANDROID_ROOT/com.android.i18n" 452 fi 453fi 454 455# If ANDROID_ART_ROOT is not set, try to detect whether we are running on 456# target or host and set that environment variable to the usual default value. 457if [ -z "$ANDROID_ART_ROOT" ]; then 458 # This script is used on host and target (device). However, the (expected) 459 # default value `ANDROID_ART_ROOT` is not the same on host and target: 460 # - on host, `ANDROID_ART_ROOT` is expected to be 461 # "$ANDROID_ROOT/com.android.art"; 462 # - on target, `ANDROID_ART_ROOT` is expected to be 463 # "/apex/com.android.art". 464 # 465 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to 466 # determine whether we are on target or host (this is brittle, but simple). 467 if [ -d "$ANDROID_ROOT/../apex" ]; then 468 # Target case. 469 ANDROID_ART_ROOT="/apex/com.android.art" 470 else 471 # Host case. 472 ANDROID_ART_ROOT="$ANDROID_ROOT/com.android.art" 473 fi 474fi 475 476# If ANDROID_TZDATA_ROOT is not set, try to detect whether we are running on 477# target or host and set that environment variable to the usual default value. 478if [ -z "$ANDROID_TZDATA_ROOT" ]; then 479 # This script is used on host and target (device). However, the (expected) 480 # default value `ANDROID_TZDATA_ROOT` is not the same on host and target: 481 # - on host, `ANDROID_TZDATA_ROOT` is expected to be 482 # "$ANDROID_ROOT/com.android.tzdata"; 483 # - on target, `ANDROID_TZDATA_ROOT` is expected to be 484 # "/apex/com.android.tzdata". 485 # 486 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to 487 # determine whether we are on target or host (this is brittle, but simple). 488 if [ -d "$ANDROID_ROOT/../apex" ]; then 489 # Target case. 490 ANDROID_TZDATA_ROOT="/apex/com.android.tzdata" 491 else 492 # Host case. 493 ANDROID_TZDATA_ROOT="$ANDROID_ROOT/com.android.tzdata" 494 fi 495fi 496 497ART_BINARY_PATH=$ANDROID_ROOT/bin/$ART_BINARY 498 499if [ ! -x "$ART_BINARY_PATH" ]; then 500 cat 1>&2 <<EOF 501Android Runtime not found: $ART_BINARY_PATH 502This script should be in the same directory as the Android Runtime ($ART_BINARY). 503EOF 504 exit 1 505fi 506 507DEX2OAT_BINARY_PATH=$ANDROID_ROOT/bin/$DEX2OAT_BINARY$DEX2OAT_SUFFIX 508 509if [ ! -x "$DEX2OAT_BINARY_PATH" ]; then 510 echo "Warning: Android Compiler not found: $DEX2OAT_BINARY_PATH" 511fi 512 513###################################### 514# Main program 515###################################### 516 517# If android logging is not explicitly set, only print warnings and errors. 518if [ -z "$ANDROID_LOG_TAGS" ]; then 519 ANDROID_LOG_TAGS='*:w' 520fi 521 522LIBDIR="$(find_libdir $ART_BINARY_PATH)" 523LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR 524DEFAULT_IMAGE_LOCATION="$(detect_boot_image_location)" 525DEX2OAT_BOOT_IMAGE="$DEFAULT_IMAGE_LOCATION" 526ISA=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH $ART_BINARY_PATH -showversion | (read art version number isa && echo $isa)) 527 528# Extract the dex2oat flags from the list of arguments. 529# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array 530# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH 531# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE 532extract_dex2oat_flags "$@" 533 534# If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own, 535# and ensure we delete it at the end. 536if [ "$ANDROID_DATA" = "/data" ] || [ "$ANDROID_DATA" = "" ]; then 537 if [[ $PWD != / ]]; then 538 ANDROID_DATA="$PWD/android-data$$" 539 else 540 # Use /data/local/tmp when running this from adb shell, since it starts out in / 541 # by default. 542 ANDROID_DATA="$ANDROID_DATA/local/tmp/android-data$$" 543 fi 544 mkdir -p "$ANDROID_DATA" 545 DELETE_ANDROID_DATA="yes" 546fi 547 548if [[ "$DEX2OAT_BCP" = "" && "$DEX2OAT_BCP_LOCS" != "" ]]; then 549 echo "Cannot use -Xbootclasspath-locations without -Xbootclasspath" 550 exit 1 551fi 552 553# Create boot class path filename or location list. 554# It takes one optional argument which is the prefix to be inserted before each entry. 555function get_boot_class_path() { 556 # Note: This must start with the CORE_IMG_JARS in Android.common_path.mk 557 local modules="core-oj core-libart okhttp bouncycastle apache-xml core-icu4j conscrypt" 558 local prefix="$1" 559 local result="" 560 local separator="" 561 for module in ${modules}; do 562 case "$module" in 563 (conscrypt) local apex="com.android.conscrypt";; 564 (core-icu4j) local apex="com.android.i18n";; 565 (*) local apex="com.android.art";; 566 esac 567 result+="${separator}${prefix}/apex/${apex}/javalib/${module}.jar" 568 separator=":" 569 done 570 echo "$result" 571} 572 573# Create default boot class path if none was provided. 574if [[ "$DEX2OAT_BCP" = "" ]]; then 575 ANDROID_ROOT_MINUS_PWD="${ANDROID_ROOT#$PWD/}" # For example: out/host/linux-x86 576 if [[ "$ANDROID_ROOT_MINUS_PWD" == */host/* ]]; then 577 DEX2OAT_BCP="$(get_boot_class_path $ANDROID_ROOT)" 578 DEX2OAT_BCP_LOCS="$(get_boot_class_path $ANDROID_ROOT_MINUS_PWD)" 579 elif [[ "$ANDROID_ROOT_MINUS_PWD" == */target/* ]]; then 580 DEX2OAT_BCP="$(get_boot_class_path $ANDROID_ROOT)" 581 DEX2OAT_BCP_LOCS="$(get_boot_class_path)" 582 else 583 echo "Can not determine whether are running on host or target" 584 exit 1 585 fi 586 if [ "$VERBOSE" = "yes" ]; then 587 echo ANDROID_ROOT=$ANDROID_ROOT 588 echo DEX2OAT_BOOT_IMAGE=$DEX2OAT_BOOT_IMAGE 589 echo DEX2OAT_BCP=$DEX2OAT_BCP 590 echo DEX2OAT_BCP_LOCS=$DEX2OAT_BCP_LOCS 591 fi 592fi 593 594if [ "$DEX2OAT_BCP" != "" ]; then 595 EXTRA_OPTIONS+=("-Xbootclasspath:$DEX2OAT_BCP") 596 DEX2OAT_FLAGS+=("--runtime-arg" "-Xbootclasspath:$DEX2OAT_BCP") 597 if [ "$DEX2OAT_BCP_LOCS" != "" ]; then 598 EXTRA_OPTIONS+=("-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS") 599 DEX2OAT_FLAGS+=("--runtime-arg" \ 600 "-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS") 601 fi 602fi 603 604if [ "$PERF" != "" ]; then 605 LAUNCH_WRAPPER="perf record -g --call-graph dwarf -F 10000 -o $ANDROID_DATA/perf.data -e cycles:u $LAUNCH_WRAPPER" 606 DEX2OAT_FLAGS+=(--generate-debug-info) 607fi 608 609if [ "$ALLOW_DEFAULT_JDWP" = "no" ]; then 610 EXTRA_OPTIONS+=(-XjdwpProvider:none) 611fi 612 613# First cleanup any left-over 'oat' files from the last time dalvikvm was run. 614cleanup_oat_directory_for_classpath "$@" 615 616# Protect additional arguments in quotes to preserve whitespaces (used by 617# run-jdwp-test.sh when running on device), '$' (may be used as part of 618# classpath) and other special characters when evaluated. 619EXTRA_OPTIONS+=("$@") 620 621if [ "$JIT_PROFILE" = "yes" ]; then 622 # Create the profile. The runtime expects profiles to be created before 623 # execution. 624 PROFILE_PATH="$ANDROID_DATA/primary.prof" 625 touch "$PROFILE_PATH" 626 627 run_art -Xjitsaveprofilinginfo \ 628 -Xps-min-methods-to-save:1 \ 629 -Xps-min-classes-to-save:1 \ 630 -Xps-min-notification-before-wake:10 \ 631 -Xps-profile-path:$PROFILE_PATH \ 632 -Xusejit:true \ 633 ${EXTRA_OPTIONS[@]} \ 634 &> "$ANDROID_DATA/profile_gen.log" 635 EXIT_STATUS=$? 636 637 if [ $EXIT_STATUS != 0 ]; then 638 echo "Profile run failed: " >&2 639 cat "$ANDROID_DATA/profile_gen.log" >&2 640 clean_android_data 641 exit $EXIT_STATUS 642 fi 643 644 # Wipe dalvik-cache so that a subsequent run_art must regenerate it. 645 # Leave $ANDROID_DATA intact since it contains our profile file. 646 rm -rf "$ANDROID_DATA/dalvik-cache" 647 648 # Append arguments so next invocation of run_art uses the profile. 649 DEX2OAT_FLAGS+=(--profile-file="$PROFILE_PATH") 650fi 651 652if [ -x "$DEX2OAT_BINARY_PATH" ]; then 653 if [ "$RUN_DEX2OAT" = "yes" ]; then 654 # Run dex2oat before launching ART to generate the oat files for the classpath. 655 run_dex2oat 656 fi 657fi 658 659# Do not continue if the dex2oat failed. 660EXIT_STATUS=$? 661if [ $EXIT_STATUS != 0 ]; then 662 echo "Failed dex2oat invocation" >&2 663 exit $EXIT_STATUS 664fi 665 666run_art "${EXTRA_OPTIONS[@]}" 667EXIT_STATUS=$? 668 669if [ "$PERF" != "" ]; then 670 if [ "$PERF" = report ]; then 671 perf report -i $ANDROID_DATA/perf.data 672 fi 673 echo "Perf data saved in: $ANDROID_DATA/perf.data" 674else 675 # Perf output is placed under $ANDROID_DATA so not cleaned when perf options used. 676 clean_android_data 677fi 678 679exit $EXIT_STATUS 680