blob: fe74614d2fd795d2cfc8264d37d4e6216be975ed [file] [log] [blame]
Elliott Hughes40ef99e2011-08-11 17:44:34 -07001# 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
Nicolas Geoffray70a998c2014-12-04 17:05:22 +000015# 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
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +010019######################################
20# Functions
21######################################
Nicolas Geoffrayfc3c67a2014-07-02 14:57:53 +010022function find_libdir() {
Orion Hodson9763f2e2017-03-28 08:27:23 +010023 # Get the actual file, $1 is the ART_BINARY_PATH and may be a symbolic link.
Nicolas Geoffray70a998c2014-12-04 17:05:22 +000024 # Use realpath instead of readlink because Android does not have a readlink.
Orion Hodson9763f2e2017-03-28 08:27:23 +010025 if [[ "$(realpath "$1")" == *dalvikvm64 ]]; then
Nicolas Geoffrayfc3c67a2014-07-02 14:57:53 +010026 echo "lib64"
27 else
28 echo "lib"
29 fi
30}
31
Orion Hodson9763f2e2017-03-28 08:27:23 +010032function usage() {
33 cat 1>&2 <<EOF
34Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +010035
Orion Hodson9763f2e2017-03-28 08:27:23 +010036Supported OPTIONS include:
37 --32 Use the 32-bit Android Runtime.
38 --64 Use the 64-bit Android Runtime.
Orion Hodson9763f2e2017-03-28 08:27:23 +010039 -d Use the debug ART library (libartd.so).
40 --debug Equivalent to -d.
41 --gdb Launch the Android Runtime in gdb.
Alex Light84b92e02017-09-29 13:46:14 -070042 --gdbserver <comms> Launch the Android Runtime in gdbserver using the
43 supplied communication channel.
Orion Hodson9763f2e2017-03-28 08:27:23 +010044 --help Display usage message.
45 --invoke-with <program> Launch the Android Runtime in <program>.
46 --perf Launch the Android Runtime with perf recording.
47 --perf-report Launch the Android Runtime with perf recording with
48 report upon completion.
49 --profile Run with profiling, then run using profile data.
50 --verbose Run script verbosely.
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +010051 --no-clean Don't cleanup oat directories.
Nicolas Geoffrayf983c732018-09-12 09:27:29 +010052 --no-compile Don't invoke dex2oat before running.
Alex Lighta4817fb2018-06-12 10:56:35 -070053 --allow-default-jdwp Don't automatically put in -XjdwpProvider:none.
54 You probably do not want this.
Orion Hodson9763f2e2017-03-28 08:27:23 +010055
56The ART_OPTIONS are passed directly to the Android Runtime.
57
58Example:
59 art --32 -cp my_classes.dex MainClass
60
61Common errors:
62 1) Not having core.art available (see $ANDROID_BUILD_TOP/art/Android.mk).
63 eg m -j32 build-art-host
64 2) Not having boot.art available (see $ANDROID_BUILD_TOP/build/make/core/dex_preopt_libart_boot.mk)
65 eg m -j32 out/target/product/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art
66EOF
67}
68
69function clean_android_data() {
70 if [ "$DELETE_ANDROID_DATA" = "yes" ]; then
Nicolas Geoffrayb487c572018-09-17 12:17:09 +000071 rm -rf $ANDROID_DATA
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +010072 fi
Orion Hodson9763f2e2017-03-28 08:27:23 +010073}
74
Vladimir Markoafd44ea2017-07-14 13:52:02 +010075# Given 'VAR1=VAL VAR2=VAL2 ... cmd arg1 arg2 ... argN' run the 'cmd' with the args
76# with the modified environment {VAR1=VAL,VAL2=,...}.
77#
78# Also prints the command to be run if verbose mode is enabled.
Orion Hodson9763f2e2017-03-28 08:27:23 +010079function verbose_run() {
80 if [ "$VERBOSE" = "yes" ]; then
81 echo "$@"
82 fi
Vladimir Markoafd44ea2017-07-14 13:52:02 +010083
Nicolas Geoffrayb487c572018-09-17 12:17:09 +000084 env "$@"
Orion Hodson9763f2e2017-03-28 08:27:23 +010085}
86
Nicolas Geoffray162a5702017-08-04 09:28:32 +000087# Parse a colon-separated list into an array (e.g. "foo.dex:bar.dex" -> (foo.dex bar.dex))
88PARSE_CLASSPATH_RESULT=() # Return value will be here due to shell limitations.
89parse_classpath() {
90 local cp="$1"
91 local oldifs=$IFS
92
93 local cp_array
94 cp_array=()
95
96 IFS=":"
97 for part in $cp; do
98 cp_array+=("$part")
99 done
100 IFS=$oldifs
101
102 PARSE_CLASSPATH_RESULT=("${cp_array[@]}")
103}
104
105# Sets 'PARSE_CLASSPATH_RESULT' to an array of class path dex files.
106# e.g. (-cp foo/classes.dex:bar/classes.dex) -> (foo/classes.dex bar/classes.dex)
107find_cp_in_args() {
108 local found="false"
109 local index=0
110 local what
111
112 while [[ $# -gt 0 ]]; do
113 case "$1" in
114 -cp|-classpath)
115 parse_classpath "$2"
116 # Sets 'PARSE_CLASSPATH_RESULT' to an array of class path dex files.
117 # Subsequent parses will overwrite the preceding.
118 shift
119 ;;
120 esac
121 shift
122 done
123}
124
125# Delete the 'oat' directories relative to the classpath's dex files.
126# e.g. (foo/classes.dex bar/classes.dex) would delete (foo/oat bar/oat) directories.
127cleanup_oat_directory() {
128 local classpath
129 classpath=("$@")
130
131 local dirpath
132
133 for path in "${classpath[@]}"; do
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000134 dirpath="$(dirname "$path")"
135 [[ -d "$dirpath" ]] && verbose_run rm -rf "$dirpath/oat"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000136 done
137}
138
139# Parse -cp <CP>, -classpath <CP>, and $CLASSPATH to find the dex files.
140# Each dex file's directory will have an 'oat' file directory, delete it.
141# Input: Command line arguments to the art script.
142# e.g. -cp foo/classes.dex:bar/classes.dex would delete (foo/oat bar/oat) directories.
143cleanup_oat_directory_for_classpath() {
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100144 if [ "$CLEAN_OAT_FILES" = "yes" ]; then
145 # First try: Use $CLASSPATH environment variable.
146 parse_classpath "$CLASSPATH"
147 # Second try: Look for latest -cp or -classpath arg which will take precedence.
148 find_cp_in_args "$@"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000149
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100150 cleanup_oat_directory "${PARSE_CLASSPATH_RESULT[@]}"
151 fi
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000152}
153
Igor Murashkind54ac262017-07-26 11:16:23 -0700154# Attempt to find $ANDROID_ROOT/framework/<isa>/core.art' without knowing what <isa> is.
155function check_if_boot_image_file_exists() {
156 local image_location_dir="$1"
157 local image_location_name="$2"
158
159 # Expand image_files to a list of existing image files on the disk.
160 # If no such files exist, it expands to single element 'dir/*/file' with a literal '*'.
161 local image_files
162 image_files=("$image_location_dir"/*/"$image_location_name") # avoid treating "*" as literal.
163
164 # Array always has at least 1 element. Test explicitly whether the file exists.
165 [[ -e "${image_files[0]}" ]]
166}
167
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700168# Automatically find the boot image location. It uses core.art by default.
169# On a real device, it might only have a boot.art, so use that instead when core.art does not exist.
170function detect_boot_image_location() {
171 local image_location_dir="$ANDROID_ROOT/framework"
172 local image_location_name="core.art"
173
Igor Murashkind54ac262017-07-26 11:16:23 -0700174 # If there are no existing core.art, try to find boot.art.
175 # If there is no boot.art then leave it as-is, assumes -Ximage is explicitly used.
176 # Otherwise let dalvikvm give the error message about an invalid image file.
177 if ! check_if_boot_image_file_exists "$image_location_dir" "core.art" && \
178 check_if_boot_image_file_exists "$image_location_dir" "boot.art"; then
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700179 image_location_name="boot.art"
180 fi
181
182 local image_location="$image_location_dir/$image_location_name"
183 echo "$image_location"
184}
185
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100186function run_dex2oat() {
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100187 local class_loader_context=
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100188 for dex_file in "${DEX2OAT_CLASSPATH[@]}"
189 do
190 while [ -h "$dex_file" ]; do
191 # On Mac OS, readlink -f doesn't work.
192 dex_file="$(readlink "$dex_file")"
193 done
194 # Create oat file directory.
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000195 verbose_run mkdir -p $(dirname "$dex_file")/oat/$ISA
196 local oat_file=$(basename "$dex_file")
197 local oat_file=$(dirname "$dex_file")/oat/$ISA/${oat_file%.*}.odex
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100198 # When running dex2oat use the exact same context as when running dalvikvm.
199 # (see run_art function)
200 verbose_run ANDROID_DATA=$ANDROID_DATA \
201 ANDROID_ROOT=$ANDROID_ROOT \
Victor Chang64611242019-07-05 16:32:41 +0100202 ANDROID_I18N_ROOT=$ANDROID_I18N_ROOT \
Martin Stjernholme58624f2019-09-20 15:53:40 +0100203 ANDROID_ART_ROOT=$ANDROID_ART_ROOT \
Neil Fuller26a5dd62019-03-13 15:16:35 +0000204 ANDROID_TZDATA_ROOT=$ANDROID_TZDATA_ROOT \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100205 LD_LIBRARY_PATH=$LD_LIBRARY_PATH \
206 PATH=$ANDROID_ROOT/bin:$PATH \
207 LD_USE_LOAD_BIAS=1 \
208 ANDROID_LOG_TAGS=$ANDROID_LOG_TAGS \
209 $DEX2OAT_BINARY_PATH \
210 --runtime-arg -Xnorelocate \
211 --boot-image=$DEX2OAT_BOOT_IMAGE \
212 --instruction-set=$ISA \
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100213 --class-loader-context="PCL[$class_loader_context]" \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100214 "${DEX2OAT_FLAGS[@]}" \
215 --dex-file=$dex_file \
216 --oat-file=$oat_file
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100217 if [[ -n $class_loader_context ]]; then
218 class_loader_context+=":"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100219 fi
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100220 class_loader_context+="$dex_file"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100221 done
222}
223
224# Extract the dex2oat flags from the list of arguments.
225# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array
226# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH
227# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE
Vladimir Markobf68e572018-12-21 11:45:35 +0000228# -Xbootclasspath argument is stored in DEX2OAT_BCP
229# -Xbootclasspath-locations argument is stored in DEX2OAT_BCP_LOCS
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100230function extract_dex2oat_flags() {
231 while [ $# -gt 0 ]; do
232 case $1 in
233 -Xcompiler-option)
234 DEX2OAT_FLAGS+=("$2")
235 shift
236 ;;
237 -Ximage:*)
Nicolas Geoffray686801f2018-08-26 16:00:53 +0100238 DEX2OAT_BOOT_IMAGE=$1
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100239 # Remove '-Ximage:' from the argument.
240 DEX2OAT_BOOT_IMAGE=${DEX2OAT_BOOT_IMAGE##-Ximage:}
241 ;;
Vladimir Markobf68e572018-12-21 11:45:35 +0000242 -Xbootclasspath:*)
243 DEX2OAT_BCP=$1
244 # Remove '-Xbootclasspath:' from the argument.
245 DEX2OAT_BCP=${DEX2OAT_BCP##-Xbootclasspath:}
246 ;;
247 -Xbootclasspath-locations:*)
248 DEX2OAT_BCP_LOCS=$1
249 # Remove '-Xbootclasspath-locations:' from the argument.
250 DEX2OAT_BCP_LOCS=${DEX2OAT_BCP_LOCS##-Xbootclasspath-locations:}
251 ;;
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100252 -cp)
Nicolas Geoffray686801f2018-08-26 16:00:53 +0100253 # Reset any previously parsed classpath, just like dalvikvm
254 # only supports one -cp argument.
255 DEX2OAT_CLASSPATH=()
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100256 # TODO: support -classpath and CLASSPATH
257 local oifs=$IFS
258 IFS=':'
259 for classpath_elem in $2
260 do
261 DEX2OAT_CLASSPATH+=("$classpath_elem")
262 done
263 shift
264 IFS=$oifs
265 ;;
266 esac
267 shift
268 done
269}
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100270
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000271# Runs dalvikvm, returns its exit code.
272# (Oat directories are cleaned up in between runs)
Orion Hodson9763f2e2017-03-28 08:27:23 +0100273function run_art() {
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000274 local ret
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700275
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000276 # Run dalvikvm.
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100277 verbose_run ANDROID_DATA="$ANDROID_DATA" \
278 ANDROID_ROOT="$ANDROID_ROOT" \
Martin Stjernholme58624f2019-09-20 15:53:40 +0100279 ANDROID_I18N_ROOT="$ANDROID_I18N_ROOT" \
280 ANDROID_ART_ROOT="$ANDROID_ART_ROOT" \
Neil Fuller26a5dd62019-03-13 15:16:35 +0000281 ANDROID_TZDATA_ROOT="$ANDROID_TZDATA_ROOT" \
Nicolas Geoffrayffda8b82017-10-06 13:48:08 +0100282 LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
283 PATH="$ANDROID_ROOT/bin:$PATH" \
284 LD_USE_LOAD_BIAS=1 \
285 ANDROID_LOG_TAGS="$ANDROID_LOG_TAGS" \
286 $LAUNCH_WRAPPER $ART_BINARY_PATH $lib \
287 -XXlib:"$LIBART" \
288 -Xnorelocate \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100289 -Ximage:"$DEFAULT_IMAGE_LOCATION" \
Orion Hodson9763f2e2017-03-28 08:27:23 +0100290 "$@"
Nicolas Geoffray162a5702017-08-04 09:28:32 +0000291 ret=$?
292
293 # Avoid polluting disk with 'oat' files after dalvikvm has finished.
294 cleanup_oat_directory_for_classpath "$@"
295
296 # Forward exit code of dalvikvm.
297 return $ret
Orion Hodson9763f2e2017-03-28 08:27:23 +0100298}
299
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100300######################################
301# Globals
302######################################
303ART_BINARY=dalvikvm
304DEX2OAT_BINARY=dex2oat
Nicolas Geoffray745e45d2020-04-21 14:09:58 +0100305DEX2OAT_SUFFIX=""
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100306DELETE_ANDROID_DATA="no"
307LAUNCH_WRAPPER=
308LIBART=libart.so
309JIT_PROFILE="no"
310ALLOW_DEFAULT_JDWP="no"
311VERBOSE="no"
312CLEAN_OAT_FILES="yes"
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100313RUN_DEX2OAT="yes"
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100314EXTRA_OPTIONS=()
315DEX2OAT_FLAGS=()
316DEX2OAT_CLASSPATH=()
317
318# Parse arguments
Orion Hodson9763f2e2017-03-28 08:27:23 +0100319while [[ "$1" = "-"* ]]; do
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100320 case "$1" in
Orion Hodson9763f2e2017-03-28 08:27:23 +0100321 --)
322 # No more arguments for this script.
323 shift
324 break
325 ;;
326 --32)
327 ART_BINARY=dalvikvm32
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100328 DEX2OAT_SUFFIX=32
Orion Hodson9763f2e2017-03-28 08:27:23 +0100329 ;;
330 --64)
331 ART_BINARY=dalvikvm64
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100332 DEX2OAT_SUFFIX=64
Orion Hodson9763f2e2017-03-28 08:27:23 +0100333 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100334 -d)
335 ;& # Fallthrough
336 --debug)
337 LIBART="libartd.so"
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100338 DEX2OAT_BINARY="dex2oatd"
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700339 # Expect that debug mode wants all checks.
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100340 EXTRA_OPTIONS+=(-XX:SlowDebug=true)
Orion Hodson9763f2e2017-03-28 08:27:23 +0100341 ;;
Alex Light84b92e02017-09-29 13:46:14 -0700342 --gdbserver)
343 LAUNCH_WRAPPER="gdbserver $2"
344 shift
345 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100346 --gdb)
347 LIBART="libartd.so"
348 LAUNCH_WRAPPER="gdb --args"
349 ;;
350 --help)
351 usage
352 exit 0
353 ;;
354 --invoke-with)
355 LAUNCH_WRAPPER=$2
356 shift
357 ;;
358 --perf)
359 PERF="record"
360 ;;
361 --perf-report)
362 PERF="report"
363 ;;
364 --profile)
365 JIT_PROFILE="yes"
366 ;;
367 --verbose)
368 VERBOSE="yes"
369 ;;
Nicolas Geoffrayc0c07852017-08-08 09:44:15 +0100370 --no-clean)
371 CLEAN_OAT_FILES="no"
372 ;;
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100373 --no-compile)
374 CLEAN_OAT_FILES="no"
375 RUN_DEX2OAT="no"
376 ;;
Alex Lighta4817fb2018-06-12 10:56:35 -0700377 --allow-default-jdwp)
378 ALLOW_DEFAULT_JDWP="yes"
379 ;;
Orion Hodson9763f2e2017-03-28 08:27:23 +0100380 --*)
381 echo "unknown option: $1" 1>&2
382 usage
383 exit 1
384 ;;
385 *)
386 break
387 ;;
388 esac
389 shift
Nicolas Geoffrayf63a0a52014-09-02 15:24:25 +0100390done
391
Orion Hodson9763f2e2017-03-28 08:27:23 +0100392if [ $# -eq 0 ]; then
393 usage
394 exit 1
395fi
396
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100397# Follow all sym links to get the program name.
Nicolas Geoffray6b09b392018-08-29 13:29:01 +0100398if [[ -n "$BASH_SOURCE" ]]; then
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100399 PROG_NAME="$BASH_SOURCE"
400else
401 PROG_NAME="$0"
402fi
403while [ -h "$PROG_NAME" ]; do
404 # On Mac OS, readlink -f doesn't work.
405 PROG_NAME="$(readlink "$PROG_NAME")"
406done
407
Brian Carlstrom87bb26f2014-09-08 11:13:47 -0700408PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
Vladimir Markobf68e572018-12-21 11:45:35 +0000409ANDROID_ROOT="$(cd $PROG_DIR/..; pwd -P)"
Roland Levillain42807522019-01-15 12:49:36 +0000410
Victor Chang64611242019-07-05 16:32:41 +0100411# If ANDROID_I18N_ROOT is not set, try to detect whether we are running on
412# target or host and set that environment variable to the usual default value.
413if [ -z "$ANDROID_I18N_ROOT" ]; then
414 # This script is used on host and target (device). However, the (expected)
415 # default value `ANDROID_I18N_ROOT` is not the same on host and target:
416 # - on host, `ANDROID_I18N_ROOT` is expected to be
417 # "$ANDROID_ROOT/com.android.i18n";
418 # - on target, `ANDROID_I18N_ROOT` is expected to be
419 # "/apex/com.android.i18n".
420 #
421 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to
422 # determine whether we are on target or host (this is brittle, but simple).
423 if [ -d "$ANDROID_ROOT/../apex" ]; then
424 # Target case.
425 ANDROID_I18N_ROOT="/apex/com.android.i18n"
426 else
427 # Host case.
428 ANDROID_I18N_ROOT="$ANDROID_ROOT/com.android.i18n"
429 fi
430fi
431
Martin Stjernholme58624f2019-09-20 15:53:40 +0100432# If ANDROID_ART_ROOT is not set, try to detect whether we are running on
Roland Levillain42807522019-01-15 12:49:36 +0000433# target or host and set that environment variable to the usual default value.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100434if [ -z "$ANDROID_ART_ROOT" ]; then
Roland Levillain42807522019-01-15 12:49:36 +0000435 # This script is used on host and target (device). However, the (expected)
Martin Stjernholme58624f2019-09-20 15:53:40 +0100436 # default value `ANDROID_ART_ROOT` is not the same on host and target:
437 # - on host, `ANDROID_ART_ROOT` is expected to be
Martin Stjernholmad909af2019-07-16 17:02:44 +0100438 # "$ANDROID_ROOT/com.android.art";
Martin Stjernholme58624f2019-09-20 15:53:40 +0100439 # - on target, `ANDROID_ART_ROOT` is expected to be
Martin Stjernholmad909af2019-07-16 17:02:44 +0100440 # "/apex/com.android.art".
Roland Levillain01631342019-01-10 18:07:24 +0000441 #
Roland Levillain42807522019-01-15 12:49:36 +0000442 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to
443 # determine whether we are on target or host (this is brittle, but simple).
444 if [ -d "$ANDROID_ROOT/../apex" ]; then
445 # Target case.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100446 ANDROID_ART_ROOT="/apex/com.android.art"
Roland Levillain42807522019-01-15 12:49:36 +0000447 else
448 # Host case.
Martin Stjernholme58624f2019-09-20 15:53:40 +0100449 ANDROID_ART_ROOT="$ANDROID_ROOT/com.android.art"
Roland Levillain42807522019-01-15 12:49:36 +0000450 fi
Roland Levillain01631342019-01-10 18:07:24 +0000451fi
452
Neil Fuller90ffe122019-06-06 17:25:48 +0100453# If ANDROID_TZDATA_ROOT is not set, try to detect whether we are running on
454# target or host and set that environment variable to the usual default value.
Neil Fuller26a5dd62019-03-13 15:16:35 +0000455if [ -z "$ANDROID_TZDATA_ROOT" ]; then
Neil Fuller90ffe122019-06-06 17:25:48 +0100456 # This script is used on host and target (device). However, the (expected)
457 # default value `ANDROID_TZDATA_ROOT` is not the same on host and target:
458 # - on host, `ANDROID_TZDATA_ROOT` is expected to be
459 # "$ANDROID_ROOT/com.android.tzdata";
460 # - on target, `ANDROID_TZDATA_ROOT` is expected to be
Roland Levillain2cd94372019-07-05 13:26:54 +0100461 # "/apex/com.android.tzdata".
Neil Fuller90ffe122019-06-06 17:25:48 +0100462 #
463 # We use the presence/absence of the `$ANDROID_ROOT/../apex` directory to
464 # determine whether we are on target or host (this is brittle, but simple).
465 if [ -d "$ANDROID_ROOT/../apex" ]; then
466 # Target case.
Roland Levillain2cd94372019-07-05 13:26:54 +0100467 ANDROID_TZDATA_ROOT="/apex/com.android.tzdata"
Neil Fuller90ffe122019-06-06 17:25:48 +0100468 else
469 # Host case.
470 ANDROID_TZDATA_ROOT="$ANDROID_ROOT/com.android.tzdata"
471 fi
Neil Fuller26a5dd62019-03-13 15:16:35 +0000472fi
473
Orion Hodson9763f2e2017-03-28 08:27:23 +0100474ART_BINARY_PATH=$ANDROID_ROOT/bin/$ART_BINARY
Brian Carlstrom87bb26f2014-09-08 11:13:47 -0700475
Orion Hodson9763f2e2017-03-28 08:27:23 +0100476if [ ! -x "$ART_BINARY_PATH" ]; then
477 cat 1>&2 <<EOF
478Android Runtime not found: $ART_BINARY_PATH
479This script should be in the same directory as the Android Runtime ($ART_BINARY).
480EOF
481 exit 1
482fi
483
Nicolas Geoffrayb0c6cb52020-04-20 15:12:42 +0100484DEX2OAT_BINARY_PATH=$ANDROID_ROOT/bin/$DEX2OAT_BINARY$DEX2OAT_SUFFIX
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100485
486if [ ! -x "$DEX2OAT_BINARY_PATH" ]; then
487 echo "Warning: Android Compiler not found: $DEX2OAT_BINARY_PATH"
488fi
489
490######################################
491# Main program
492######################################
493
494# If android logging is not explicitly set, only print warnings and errors.
495if [ -z "$ANDROID_LOG_TAGS" ]; then
496 ANDROID_LOG_TAGS='*:w'
497fi
498
Orion Hodson9763f2e2017-03-28 08:27:23 +0100499LIBDIR="$(find_libdir $ART_BINARY_PATH)"
500LD_LIBRARY_PATH=$ANDROID_ROOT/$LIBDIR
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100501DEFAULT_IMAGE_LOCATION="$(detect_boot_image_location)"
502DEX2OAT_BOOT_IMAGE="$DEFAULT_IMAGE_LOCATION"
Nicolas Geoffray810a1002018-08-28 17:40:49 +0100503ISA=$(LD_LIBRARY_PATH=$LD_LIBRARY_PATH $ART_BINARY_PATH -showversion | (read art version number isa && echo $isa))
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100504
505# Extract the dex2oat flags from the list of arguments.
506# -Xcompiler-options arguments are stored in DEX2OAT_FLAGS array
507# -cp argument is split by ':' and stored in DEX2OAT_CLASSPATH
Nicolas Geoffray70cbbe92019-01-14 09:08:16 +0000508# -Ximage argument is stored in DEX2OAT_BOOT_IMAGE
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100509extract_dex2oat_flags "$@"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100510
Nicolas Geoffray70a998c2014-12-04 17:05:22 +0000511# If ANDROID_DATA is the system ANDROID_DATA or is not set, use our own,
512# and ensure we delete it at the end.
513if [ "$ANDROID_DATA" = "/data" ] || [ "$ANDROID_DATA" = "" ]; then
Igor Murashkin7fef4eb2017-07-14 15:45:47 -0700514 if [[ $PWD != / ]]; then
515 ANDROID_DATA="$PWD/android-data$$"
516 else
517 # Use /data/local/tmp when running this from adb shell, since it starts out in /
518 # by default.
519 ANDROID_DATA="$ANDROID_DATA/local/tmp/android-data$$"
520 fi
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000521 mkdir -p "$ANDROID_DATA"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100522 DELETE_ANDROID_DATA="yes"
Nicolas Geoffray70a998c2014-12-04 17:05:22 +0000523fi
524
Vladimir Markobf68e572018-12-21 11:45:35 +0000525if [[ "$DEX2OAT_BCP" = "" && "$DEX2OAT_BCP_LOCS" != "" ]]; then
526 echo "Cannot use -Xbootclasspath-locations without -Xbootclasspath"
527 exit 1
528fi
529
Nicolas Geoffrayd41f64c2019-01-11 15:46:41 +0000530if [[ "$DEX2OAT_BOOT_IMAGE" = *core*.art && "$DEX2OAT_BCP" = "" ]]; then
Vladimir Markobf68e572018-12-21 11:45:35 +0000531 # Note: This must start with the CORE_IMG_JARS in Android.common_path.mk
532 # because that's what we use for compiling the core.art image.
533 # It may contain additional modules from TEST_CORE_JARS.
David Srbecky5055e662020-04-22 11:49:06 +0100534 core_jars_list="core-oj core-libart core-icu4j okhttp bouncycastle apache-xml"
Vladimir Markobf68e572018-12-21 11:45:35 +0000535 core_jars_suffix=
536 if [[ -e $ANDROID_ROOT/framework/core-oj-hostdex.jar ]]; then
537 core_jars_suffix=-hostdex
David Srbecky5055e662020-04-22 11:49:06 +0100538 core_filenames_dir=$ANDROID_ROOT/framework
Vladimir Markobf68e572018-12-21 11:45:35 +0000539 core_locations_dir=$ANDROID_ROOT/framework
540 prefix=$PWD/
541 if [[ ${core_locations_dir:0:${#prefix}} = $prefix ]]; then
542 core_locations_dir="${core_locations_dir##$prefix}"
543 fi
David Srbecky5055e662020-04-22 11:49:06 +0100544 elif [[ -e $ANDROID_ROOT/apex/com.android.art.debug/javalib/core-oj.jar ]]; then
545 core_jars_suffix=
546 core_filenames_dir=$ANDROID_ROOT/apex/com.android.art.debug/javalib
547 core_locations_dir=/apex/com.android.art/javalib
548 else
549 echo "Can not find jar files for boot image $DEX2OAT_BOOT_IMAGE"
550 exit 1
551 fi
552 if [[ $core_locations_dir != "" ]]; then
Vladimir Markobf68e572018-12-21 11:45:35 +0000553 boot_separator=""
554 for boot_module in ${core_jars_list}; do
555 DEX_FILENAME="$boot_module$core_jars_suffix.jar"
David Srbecky5055e662020-04-22 11:49:06 +0100556 DEX2OAT_BCP+="$boot_separator$core_filenames_dir/${DEX_FILENAME}"
Vladimir Markobf68e572018-12-21 11:45:35 +0000557 DEX2OAT_BCP_LOCS+="$boot_separator$core_locations_dir/${DEX_FILENAME}"
558 boot_separator=":"
559 done
560 if [ "$VERBOSE" = "yes" ]; then
561 echo "Using predefined -Xbootclasspath for image $DEX2OAT_BOOT_IMAGE:"
562 echo DEX2OAT_BOOT_IMAGE=$DEX2OAT_BOOT_IMAGE
563 echo DEX2OAT_BCP=$DEX2OAT_BCP
564 echo DEX2OAT_BCP_LOCS=$DEX2OAT_BCP_LOCS
565 fi
566 fi
567fi
568
569if [ "$DEX2OAT_BCP" != "" ]; then
570 EXTRA_OPTIONS+=("-Xbootclasspath:$DEX2OAT_BCP")
571 DEX2OAT_FLAGS+=("--runtime-arg" "-Xbootclasspath:$DEX2OAT_BCP")
572 if [ "$DEX2OAT_BCP_LOCS" != "" ]; then
573 EXTRA_OPTIONS+=("-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS")
574 DEX2OAT_FLAGS+=("--runtime-arg" \
575 "-Xbootclasspath-locations:$DEX2OAT_BCP_LOCS")
576 fi
577fi
578
Orion Hodson9763f2e2017-03-28 08:27:23 +0100579if [ "$PERF" != "" ]; then
David Srbecky0dcb17f2018-08-13 12:41:47 +0100580 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 +0100581 DEX2OAT_FLAGS+=(--generate-debug-info)
Nicolas Geoffraye099a612014-12-12 13:52:00 +0000582fi
583
Alex Lighta4817fb2018-06-12 10:56:35 -0700584if [ "$ALLOW_DEFAULT_JDWP" = "no" ]; then
585 EXTRA_OPTIONS+=(-XjdwpProvider:none)
586fi
587
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100588# First cleanup any left-over 'oat' files from the last time dalvikvm was run.
589cleanup_oat_directory_for_classpath "$@"
590
591# Protect additional arguments in quotes to preserve whitespaces (used by
592# run-jdwp-test.sh when running on device), '$' (may be used as part of
593# classpath) and other special characters when evaluated.
594EXTRA_OPTIONS+=("$@")
595
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000596if [ "$JIT_PROFILE" = "yes" ]; then
597 # Create the profile. The runtime expects profiles to be created before
598 # execution.
599 PROFILE_PATH="$ANDROID_DATA/primary.prof"
Igor Murashkind54ac262017-07-26 11:16:23 -0700600 touch "$PROFILE_PATH"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000601
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000602 run_art -Xjitsaveprofilinginfo \
603 -Xps-min-methods-to-save:1 \
604 -Xps-min-classes-to-save:1 \
605 -Xps-min-notification-before-wake:10 \
606 -Xps-profile-path:$PROFILE_PATH \
607 -Xusejit:true \
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100608 ${EXTRA_OPTIONS[@]} \
Igor Murashkin11942442017-07-20 11:08:34 -0700609 &> "$ANDROID_DATA/profile_gen.log"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000610 EXIT_STATUS=$?
611
612 if [ $EXIT_STATUS != 0 ]; then
Igor Murashkind54ac262017-07-26 11:16:23 -0700613 echo "Profile run failed: " >&2
614 cat "$ANDROID_DATA/profile_gen.log" >&2
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000615 clean_android_data
616 exit $EXIT_STATUS
617 fi
618
Igor Murashkind54ac262017-07-26 11:16:23 -0700619 # Wipe dalvik-cache so that a subsequent run_art must regenerate it.
620 # Leave $ANDROID_DATA intact since it contains our profile file.
Nicolas Geoffrayb487c572018-09-17 12:17:09 +0000621 rm -rf "$ANDROID_DATA/dalvik-cache"
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000622
623 # Append arguments so next invocation of run_art uses the profile.
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100624 DEX2OAT_FLAGS+=(--profile-file="$PROFILE_PATH")
Nicolas Geoffray9d7baf42017-04-19 09:01:29 +0000625fi
626
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100627if [ -x "$DEX2OAT_BINARY_PATH" ]; then
Nicolas Geoffrayf983c732018-09-12 09:27:29 +0100628 if [ "$RUN_DEX2OAT" = "yes" ]; then
629 # Run dex2oat before launching ART to generate the oat files for the classpath.
630 run_dex2oat
631 fi
Nicolas Geoffray335c4ce2018-08-24 18:27:31 +0100632fi
633
634# Do not continue if the dex2oat failed.
635EXIT_STATUS=$?
636if [ $EXIT_STATUS != 0 ]; then
637 echo "Failed dex2oat invocation" >&2
638 exit $EXIT_STATUS
639fi
Calin Juravle64f45cb2017-03-16 19:58:26 -0700640
Vladimir Markoafd44ea2017-07-14 13:52:02 +0100641run_art "${EXTRA_OPTIONS[@]}"
Orion Hodson9763f2e2017-03-28 08:27:23 +0100642EXIT_STATUS=$?
Calin Juravleaa980612014-10-20 15:58:57 +0100643
Orion Hodson9763f2e2017-03-28 08:27:23 +0100644if [ "$PERF" != "" ]; then
645 if [ "$PERF" = report ]; then
Calin Juravleaa980612014-10-20 15:58:57 +0100646 perf report -i $ANDROID_DATA/perf.data
647 fi
648 echo "Perf data saved in: $ANDROID_DATA/perf.data"
649else
Orion Hodson9763f2e2017-03-28 08:27:23 +0100650 # Perf output is placed under $ANDROID_DATA so not cleaned when perf options used.
651 clean_android_data
Calin Juravleaa980612014-10-20 15:58:57 +0100652fi
653
Nicolas Geoffray89c4e282014-03-24 09:33:30 +0000654exit $EXIT_STATUS