blob: e545fc39f771a0338b4c81cf1539d75a058944e5 [file] [log] [blame]
Martin Stjernholm8c7e2192020-06-26 15:54:16 +01001#! /bin/sh
Elliott Hughes40ef99e2011-08-11 17:44:34 -07002# 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
Nicolas Geoffray70a998c2014-12-04 17:05:22 +000016# 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
Martin Stjernholm8c7e2192020-06-26 15:54:16 +010018# 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
Nicolas Geoffray70a998c2014-12-04 17:05:22 +000023
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +010024######################################
25# Functions
26######################################
Nicolas Geoffrayfc3c67a2014-07-02 14:57:53 +010027function find_libdir() {
Orion Hodson9763f2e2017-03-28 08:27:23 +010028 # Get the actual file, $1 is the ART_BINARY_PATH and may be a symbolic link.
Nicolas Geoffray70a998c2014-12-04 17:05:22 +000029 # Use realpath instead of readlink because Android does not have a readlink.
Orion Hodson9763f2e2017-03-28 08:27:23 +010030 if [[ "$(realpath "$1")" == *dalvikvm64 ]]; then
Nicolas Geoffrayfc3c67a2014-07-02 14:57:53 +010031 echo "lib64"
32 else
33 echo "lib"
34 fi
35}
36
Orion Hodson9763f2e2017-03-28 08:27:23 +010037function usage() {
38 cat 1>&2 <<EOF
39Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +010040
Orion Hodson9763f2e2017-03-28 08:27:23 +010041Supported OPTIONS include:
42 --32 Use the 32-bit Android Runtime.
43 --64 Use the 64-bit Android Runtime.
Orion Hodson9763f2e2017-03-28 08:27:23 +010044 -d Use the debug ART library (libartd.so).
45 --debug Equivalent to -d.
46 --gdb Launch the Android Runtime in gdb.
Alex Light84b92e02017-09-29 13:46:14 -070047 --gdbserver <comms> Launch the Android Runtime in gdbserver using the
48 supplied communication channel.
Orion Hodson9763f2e2017-03-28 08:27:23 +010049 --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.
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +010056 --no-clean Don't cleanup oat directories.
Nicolas Geoffrayf983c732018-09-12 09:27:29 +010057 --no-compile Don't invoke dex2oat before running.
Alex Lighta4817fb2018-06-12 10:56:35 -070058 --allow-default-jdwp Don't automatically put in -XjdwpProvider:none.
59 You probably do not want this.
Orion Hodson9763f2e2017-03-28 08:27:23 +010060
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
Nicolas Geoffrayb487c572018-09-17 12:17:09 +000076 rm -rf $ANDROID_DATA
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +010077 fi
Orion Hodson9763f2e2017-03-28 08:27:23 +010078}
79
Vladimir Markoafd44ea2017-07-14 13:52:02 +010080# 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.
Orion Hodson9763f2e2017-03-28 08:27:23 +010084function verbose_run() {
85 if [ "$VERBOSE" = "yes" ]; then
86 echo "$@"
87 fi
Vladimir Markoafd44ea2017-07-14 13:52:02 +010088
Nicolas Geoffrayb487c572018-09-17 12:17:09 +000089 env "$@"
Orion Hodson9763f2e2017-03-28 08:27:23 +010090}
91
Nicolas Geoffray162a5702017-08-04 09:28:32 +000092# 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
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000139 dirpath="$(dirname "$path")"
140 [[ -d "$dirpath" ]] && verbose_run rm -rf "$dirpath/oat"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000141 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() {
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100149 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 "$@"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000154
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100155 cleanup_oat_directory "${PARSE_CLASSPATH_RESULT[@]}"
156 fi
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000157}
158
Igor Murashkind54ac262017-07-26 11:16:23 -0700159# 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
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700173# 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
Igor Murashkind54ac262017-07-26 11:16:23 -0700179 # 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
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700184 image_location_name="boot.art"
185 fi
186
187 local image_location="$image_location_dir/$image_location_name"
188 echo "$image_location"
189}
190
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100191function run_dex2oat() {
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100192 local class_loader_context=
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100193 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.
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000200 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
Eric Holk256c0f62020-04-28 15:51:44 -0700203 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
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100209 # 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 \
Victor Chang64611242019-07-05 16:32:41 +0100213 ANDROID_I18N_ROOT=$ANDROID_I18N_ROOT \
Martin Stjernholme58624f2019-09-20 15:53:40 +0100214 ANDROID_ART_ROOT=$ANDROID_ART_ROOT \
Neil Fuller26a5dd62019-03-13 15:16:35 +0000215 ANDROID_TZDATA_ROOT=$ANDROID_TZDATA_ROOT \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100216 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 \
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100224 --class-loader-context="PCL[$class_loader_context]" \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100225 "${DEX2OAT_FLAGS[@]}" \
226 --dex-file=$dex_file \
227 --oat-file=$oat_file
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100228 if [[ -n $class_loader_context ]]; then
229 class_loader_context+=":"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100230 fi
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100231 class_loader_context+="$dex_file"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100232 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
Vladimir Markobf68e572018-12-21 11:45:35 +0000239# -Xbootclasspath argument is stored in DEX2OAT_BCP
240# -Xbootclasspath-locations argument is stored in DEX2OAT_BCP_LOCS
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100241function extract_dex2oat_flags() {
242 while [ $# -gt 0 ]; do
243 case $1 in
244 -Xcompiler-option)
245 DEX2OAT_FLAGS+=("$2")
Eric Holk256c0f62020-04-28 15:51:44 -0700246
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
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100257 shift
258 ;;
259 -Ximage:*)
Nicolas Geoffray686801f2018-08-26 16:00:53 +0100260 DEX2OAT_BOOT_IMAGE=$1
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100261 # Remove '-Ximage:' from the argument.
262 DEX2OAT_BOOT_IMAGE=${DEX2OAT_BOOT_IMAGE##-Ximage:}
263 ;;
Vladimir Markobf68e572018-12-21 11:45:35 +0000264 -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 ;;
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100274 -cp)
Nicolas Geoffray686801f2018-08-26 16:00:53 +0100275 # Reset any previously parsed classpath, just like dalvikvm
276 # only supports one -cp argument.
277 DEX2OAT_CLASSPATH=()
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100278 # 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}
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100292
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000293# Runs dalvikvm, returns its exit code.
294# (Oat directories are cleaned up in between runs)
Orion Hodson9763f2e2017-03-28 08:27:23 +0100295function run_art() {
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000296 local ret
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700297
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000298 # Run dalvikvm.
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100299 verbose_run ANDROID_DATA="$ANDROID_DATA" \
300 ANDROID_ROOT="$ANDROID_ROOT" \
Martin Stjernholme58624f2019-09-20 15:53:40 +0100301 ANDROID_I18N_ROOT="$ANDROID_I18N_ROOT" \
302 ANDROID_ART_ROOT="$ANDROID_ART_ROOT" \
Neil Fuller26a5dd62019-03-13 15:16:35 +0000303 ANDROID_TZDATA_ROOT="$ANDROID_TZDATA_ROOT" \
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100304 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 \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100311 -Ximage:"$DEFAULT_IMAGE_LOCATION" \
Orion Hodson9763f2e2017-03-28 08:27:23 +0100312 "$@"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000313 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
Orion Hodson9763f2e2017-03-28 08:27:23 +0100320}
321
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100322######################################
323# Globals
324######################################
325ART_BINARY=dalvikvm
326DEX2OAT_BINARY=dex2oat
Nicolas Geoffray745e45d2020-04-21 14:09:58 +0100327DEX2OAT_SUFFIX=""
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100328DELETE_ANDROID_DATA="no"
329LAUNCH_WRAPPER=
330LIBART=libart.so
331JIT_PROFILE="no"
332ALLOW_DEFAULT_JDWP="no"
333VERBOSE="no"
334CLEAN_OAT_FILES="yes"
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100335RUN_DEX2OAT="yes"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100336EXTRA_OPTIONS=()
337DEX2OAT_FLAGS=()
338DEX2OAT_CLASSPATH=()
Eric Holk256c0f62020-04-28 15:51:44 -0700339GENERATE_APP_IMAGE="no"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100340
341# Parse arguments
Orion Hodson9763f2e2017-03-28 08:27:23 +0100342while [[ "$1" = "-"* ]]; do
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100343 case "$1" in
Orion Hodson9763f2e2017-03-28 08:27:23 +0100344 --)
345 # No more arguments for this script.
346 shift
347 break
348 ;;
349 --32)
350 ART_BINARY=dalvikvm32
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100351 DEX2OAT_SUFFIX=32
Orion Hodson9763f2e2017-03-28 08:27:23 +0100352 ;;
353 --64)
354 ART_BINARY=dalvikvm64
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100355 DEX2OAT_SUFFIX=64
Orion Hodson9763f2e2017-03-28 08:27:23 +0100356 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100357 -d)
358 ;& # Fallthrough
359 --debug)
360 LIBART="libartd.so"
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100361 DEX2OAT_BINARY="dex2oatd"
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700362 # Expect that debug mode wants all checks.
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100363 EXTRA_OPTIONS+=(-XX:SlowDebug=true)
Orion Hodson9763f2e2017-03-28 08:27:23 +0100364 ;;
Alex Light84b92e02017-09-29 13:46:14 -0700365 --gdbserver)
366 LAUNCH_WRAPPER="gdbserver $2"
367 shift
368 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100369 --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 ;;
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100393 --no-clean)
394 CLEAN_OAT_FILES="no"
395 ;;
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100396 --no-compile)
397 CLEAN_OAT_FILES="no"
398 RUN_DEX2OAT="no"
399 ;;
Alex Lighta4817fb2018-06-12 10:56:35 -0700400 --allow-default-jdwp)
401 ALLOW_DEFAULT_JDWP="yes"
402 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100403 --*)
404 echo "unknown option: $1" 1>&2
405 usage
406 exit 1
407 ;;
408 *)
409 break
410 ;;
411 esac
412 shift
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +0100413done
414
Orion Hodson9763f2e2017-03-28 08:27:23 +0100415if [ $# -eq 0 ]; then
416 usage
417 exit 1
418fi
419
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100420# Follow all sym links to get the program name.
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100421if [[ -n "$BASH_SOURCE" ]]; then
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100422 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
Brian Carlstrom87bb26f2014-09-08 11:13:47 -0700431PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
Vladimir Markobf68e572018-12-21 11:45:35 +0000432ANDROID_ROOT="$(cd $PROG_DIR/..; pwd -P)"
Roland Levillain42807522019-01-15 12:49:36 +0000433
Victor Chang64611242019-07-05 16:32:41 +0100434# 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
Martin Stjernholme58624f2019-09-20 15:53:40 +0100455# If ANDROID_ART_ROOT is not set, try to detect whether we are running on
Roland Levillain42807522019-01-15 12:49:36 +0000456# target or host and set that environment variable to the usual default value.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100457if [ -z "$ANDROID_ART_ROOT" ]; then
Roland Levillain42807522019-01-15 12:49:36 +0000458 # This script is used on host and target (device). However, the (expected)
Martin Stjernholme58624f2019-09-20 15:53:40 +0100459 # default value `ANDROID_ART_ROOT` is not the same on host and target:
460 # - on host, `ANDROID_ART_ROOT` is expected to be
Martin Stjernholmad909af2019-07-16 17:02:44 +0100461 # "$ANDROID_ROOT/com.android.art";
Martin Stjernholme58624f2019-09-20 15:53:40 +0100462 # - on target, `ANDROID_ART_ROOT` is expected to be
Martin Stjernholmad909af2019-07-16 17:02:44 +0100463 # "/apex/com.android.art".
Roland Levillain01631342019-01-10 18:07:24 +0000464 #
Roland Levillain42807522019-01-15 12:49:36 +0000465 # 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.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100469 ANDROID_ART_ROOT="/apex/com.android.art"
Roland Levillain42807522019-01-15 12:49:36 +0000470 else
471 # Host case.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100472 ANDROID_ART_ROOT="$ANDROID_ROOT/com.android.art"
Roland Levillain42807522019-01-15 12:49:36 +0000473 fi
Roland Levillain01631342019-01-10 18:07:24 +0000474fi
475
Neil Fuller90ffe122019-06-06 17:25:48 +0100476# 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.
Neil Fuller26a5dd62019-03-13 15:16:35 +0000478if [ -z "$ANDROID_TZDATA_ROOT" ]; then
Neil Fuller90ffe122019-06-06 17:25:48 +0100479 # 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
Roland Levillain2cd94372019-07-05 13:26:54 +0100484 # "/apex/com.android.tzdata".
Neil Fuller90ffe122019-06-06 17:25:48 +0100485 #
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.
Roland Levillain2cd94372019-07-05 13:26:54 +0100490 ANDROID_TZDATA_ROOT="/apex/com.android.tzdata"
Neil Fuller90ffe122019-06-06 17:25:48 +0100491 else
492 # Host case.
493 ANDROID_TZDATA_ROOT="$ANDROID_ROOT/com.android.tzdata"
494 fi
Neil Fuller26a5dd62019-03-13 15:16:35 +0000495fi
496
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000497ART_BINARY_TARGET_PATH=$ANDROID_ART_ROOT/bin/$ART_BINARY
498ART_BINARY_HOST_PATH=$ANDROID_ROOT/bin/$ART_BINARY
Brian Carlstrom87bb26f2014-09-08 11:13:47 -0700499
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000500if [ -x "$ART_BINARY_TARGET_PATH" ]; then
501 ART_BINARY_PATH="$ART_BINARY_TARGET_PATH"
502elif [ -x "$ART_BINARY_HOST_PATH" ]; then
503 ART_BINARY_PATH="$ART_BINARY_HOST_PATH"
504else
Orion Hodson9763f2e2017-03-28 08:27:23 +0100505 cat 1>&2 <<EOF
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000506Android Runtime not found as either $ART_BINARY_TARGET_PATH or $ART_BINARY_HOST_PATH
Orion Hodson9763f2e2017-03-28 08:27:23 +0100507This script should be in the same directory as the Android Runtime ($ART_BINARY).
508EOF
509 exit 1
510fi
511
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000512DEX2OAT_BINARY_TARGET_PATH=$ANDROID_ART_ROOT/bin/$DEX2OAT_BINARY$DEX2OAT_SUFFIX
513DEX2OAT_BINARY_HOST_PATH=$ANDROID_ROOT/bin/$DEX2OAT_BINARY$DEX2OAT_SUFFIX
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100514
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000515if [ -x "$DEX2OAT_BINARY_TARGET_PATH" ]; then
516 DEX2OAT_BINARY_PATH="$DEX2OAT_BINARY_TARGET_PATH"
517elif [ -x "$DEX2OAT_BINARY_HOST_PATH" ]; then
518 DEX2OAT_BINARY_PATH="$DEX2OAT_BINARY_HOST_PATH"
519else
520 echo "Warning: Android Compiler not found as either $DEX2OAT_BINARY_TARGET_PATH or $DEX2OAT_BINARY_HOST_PATH"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100521fi
522
Martin Stjernholm79575922021-12-15 17:32:28 +0000523# Ensure the ART binary is present on PATH, in case we're in a chroot on a
524# sufficiently old device OS (b/210859761).
525if [[ ":$PATH:" != *:$ANDROID_ART_ROOT/bin:* ]]; then
526 export PATH="$PATH:$ANDROID_ART_ROOT/bin"
527fi
528
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100529######################################
530# Main program
531######################################
532
533# If android logging is not explicitly set, only print warnings and errors.
534if [ -z "$ANDROID_LOG_TAGS" ]; then
535 ANDROID_LOG_TAGS='*:w'
536fi
537
Orion Hodson9763f2e2017-03-28 08:27:23 +0100538LIBDIR="$(find_libdir $ART_BINARY_PATH)"
539LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100540DEFAULT_IMAGE_LOCATION="$(detect_boot_image_location)"
541DEX2OAT_BOOT_IMAGE="$DEFAULT_IMAGE_LOCATION"
Nicolas Geoffray810a1002018-08-28 17:40:49 +0100542ISA=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH $ART_BINARY_PATH -showversion | (read art version number isa && echo $isa))
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100543
544# Extract the dex2oat flags from the list of arguments.
545# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array
546# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH
Nicolas Geoffray70cbbe92019-01-14 09:08:16 +0000547# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100548extract_dex2oat_flags "$@"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100549
Nicolas Geoffray70a998c2014-12-04 17:05:22 +0000550# If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own,
551# and ensure we delete it at the end.
552if [ "$ANDROID_DATA" = "/data" ] || [ "$ANDROID_DATA" = "" ]; then
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700553 if [[ $PWD != / ]]; then
554 ANDROID_DATA="$PWD/android-data$$"
555 else
556 # Use /data/local/tmp when running this from adb shell, since it starts out in /
557 # by default.
558 ANDROID_DATA="$ANDROID_DATA/local/tmp/android-data$$"
559 fi
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000560 mkdir -p "$ANDROID_DATA"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100561 DELETE_ANDROID_DATA="yes"
Nicolas Geoffray70a998c2014-12-04 17:05:22 +0000562fi
563
Vladimir Markobf68e572018-12-21 11:45:35 +0000564if [[ "$DEX2OAT_BCP" = "" && "$DEX2OAT_BCP_LOCS" != "" ]]; then
565 echo "Cannot use -Xbootclasspath-locations without -Xbootclasspath"
566 exit 1
567fi
568
David Srbecky03a322d2020-05-27 17:13:13 +0100569# Create boot class path filename or location list.
570# It takes one optional argument which is the prefix to be inserted before each entry.
571function get_boot_class_path() {
Vladimir Markobf68e572018-12-21 11:45:35 +0000572 # Note: This must start with the CORE_IMG_JARS in Android.common_path.mk
David Srbecky03a322d2020-05-27 17:13:13 +0100573 local modules="core-oj core-libart okhttp bouncycastle apache-xml core-icu4j conscrypt"
574 local prefix="$1"
575 local result=""
576 local separator=""
577 for module in ${modules}; do
578 case "$module" in
579 (conscrypt) local apex="com.android.conscrypt";;
580 (core-icu4j) local apex="com.android.i18n";;
581 (*) local apex="com.android.art";;
582 esac
583 result+="${separator}${prefix}/apex/${apex}/javalib/${module}.jar"
584 separator=":"
585 done
586 echo "$result"
587}
588
589# Create default boot class path if none was provided.
590if [[ "$DEX2OAT_BCP" = "" ]]; then
591 ANDROID_ROOT_MINUS_PWD="${ANDROID_ROOT#$PWD/}" # For example: out/host/linux-x86
592 if [[ "$ANDROID_ROOT_MINUS_PWD" == */host/* ]]; then
593 DEX2OAT_BCP="$(get_boot_class_path $ANDROID_ROOT)"
594 DEX2OAT_BCP_LOCS="$(get_boot_class_path $ANDROID_ROOT_MINUS_PWD)"
595 elif [[ "$ANDROID_ROOT_MINUS_PWD" == */target/* ]]; then
596 DEX2OAT_BCP="$(get_boot_class_path $ANDROID_ROOT)"
597 DEX2OAT_BCP_LOCS="$(get_boot_class_path)"
David Srbecky5055e662020-04-22 11:49:06 +0100598 else
David Srbecky03a322d2020-05-27 17:13:13 +0100599 echo "Can not determine whether are running on host or target"
David Srbecky5055e662020-04-22 11:49:06 +0100600 exit 1
601 fi
David Srbecky03a322d2020-05-27 17:13:13 +0100602 if [ "$VERBOSE" = "yes" ]; then
603 echo ANDROID_ROOT=$ANDROID_ROOT
604 echo DEX2OAT_BOOT_IMAGE=$DEX2OAT_BOOT_IMAGE
605 echo DEX2OAT_BCP=$DEX2OAT_BCP
606 echo DEX2OAT_BCP_LOCS=$DEX2OAT_BCP_LOCS
Vladimir Markobf68e572018-12-21 11:45:35 +0000607 fi
608fi
609
610if [ "$DEX2OAT_BCP" != "" ]; then
611 EXTRA_OPTIONS+=("-Xbootclasspath:$DEX2OAT_BCP")
612 DEX2OAT_FLAGS+=("--runtime-arg" "-Xbootclasspath:$DEX2OAT_BCP")
613 if [ "$DEX2OAT_BCP_LOCS" != "" ]; then
614 EXTRA_OPTIONS+=("-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS")
615 DEX2OAT_FLAGS+=("--runtime-arg" \
616 "-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS")
617 fi
618fi
619
Orion Hodson9763f2e2017-03-28 08:27:23 +0100620if [ "$PERF" != "" ]; then
David Srbecky0dcb17f2018-08-13 12:41:47 +0100621 LAUNCH_WRAPPER="perf record -g --call-graph dwarf -F 10000 -o $ANDROID_DATA/perf.data -e cycles:u $LAUNCH_WRAPPER"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100622 DEX2OAT_FLAGS+=(--generate-debug-info)
Nicolas Geoffraye099a612014-12-12 13:52:00 +0000623fi
624
Alex Lighta4817fb2018-06-12 10:56:35 -0700625if [ "$ALLOW_DEFAULT_JDWP" = "no" ]; then
626 EXTRA_OPTIONS+=(-XjdwpProvider:none)
627fi
628
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100629# First cleanup any left-over 'oat' files from the last time dalvikvm was run.
630cleanup_oat_directory_for_classpath "$@"
631
632# Protect additional arguments in quotes to preserve whitespaces (used by
633# run-jdwp-test.sh when running on device), '$' (may be used as part of
634# classpath) and other special characters when evaluated.
635EXTRA_OPTIONS+=("$@")
636
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000637if [ "$JIT_PROFILE" = "yes" ]; then
638 # Create the profile. The runtime expects profiles to be created before
639 # execution.
640 PROFILE_PATH="$ANDROID_DATA/primary.prof"
Igor Murashkind54ac262017-07-26 11:16:23 -0700641 touch "$PROFILE_PATH"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000642
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000643 run_art -Xjitsaveprofilinginfo \
644 -Xps-min-methods-to-save:1 \
645 -Xps-min-classes-to-save:1 \
646 -Xps-min-notification-before-wake:10 \
647 -Xps-profile-path:$PROFILE_PATH \
648 -Xusejit:true \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100649 ${EXTRA_OPTIONS[@]} \
Igor Murashkin11942442017-07-20 11:08:34 -0700650 &> "$ANDROID_DATA/profile_gen.log"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000651 EXIT_STATUS=$?
652
653 if [ $EXIT_STATUS != 0 ]; then
Igor Murashkind54ac262017-07-26 11:16:23 -0700654 echo "Profile run failed: " >&2
655 cat "$ANDROID_DATA/profile_gen.log" >&2
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000656 clean_android_data
657 exit $EXIT_STATUS
658 fi
659
Igor Murashkind54ac262017-07-26 11:16:23 -0700660 # Wipe dalvik-cache so that a subsequent run_art must regenerate it.
661 # Leave $ANDROID_DATA intact since it contains our profile file.
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000662 rm -rf "$ANDROID_DATA/dalvik-cache"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000663
664 # Append arguments so next invocation of run_art uses the profile.
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100665 DEX2OAT_FLAGS+=(--profile-file="$PROFILE_PATH")
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000666fi
667
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100668if [ -x "$DEX2OAT_BINARY_PATH" ]; then
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100669 if [ "$RUN_DEX2OAT" = "yes" ]; then
670 # Run dex2oat before launching ART to generate the oat files for the classpath.
671 run_dex2oat
672 fi
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100673fi
674
675# Do not continue if the dex2oat failed.
676EXIT_STATUS=$?
677if [ $EXIT_STATUS != 0 ]; then
678 echo "Failed dex2oat invocation" >&2
679 exit $EXIT_STATUS
680fi
Calin Juravle64f45cb2017-03-16 19:58:26 -0700681
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100682run_art "${EXTRA_OPTIONS[@]}"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100683EXIT_STATUS=$?
Calin Juravleaa980612014-10-20 15:58:57 +0100684
Orion Hodson9763f2e2017-03-28 08:27:23 +0100685if [ "$PERF" != "" ]; then
686 if [ "$PERF" = report ]; then
Calin Juravleaa980612014-10-20 15:58:57 +0100687 perf report -i $ANDROID_DATA/perf.data
688 fi
689 echo "Perf data saved in: $ANDROID_DATA/perf.data"
690else
Orion Hodson9763f2e2017-03-28 08:27:23 +0100691 # Perf output is placed under $ANDROID_DATA so not cleaned when perf options used.
692 clean_android_data
Calin Juravleaa980612014-10-20 15:58:57 +0100693fi
694
Nicolas Geoffray89c4e282014-03-24 09:33:30 +0000695exit $EXIT_STATUS