1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
#!/bin/bash
#
# Copyright (C) 2020 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This script creates the framework boot image and system server profiles
# (suitable to include in the platform build).
# The input to the script are:
# 1) the boot.zip file which contains the boot classpath and system server jars.
# This file can be obtained from running `m dist` or by configuring the device with
# the `art/tools/boot-image-profile-configure-device.sh` script.
# 2) the preloaded classes denylist which specify what classes should not be preloaded
# in Zygote. Usually located in frameworks/base/config/preloaded-classes-denylist
# 3) a list of raw boot image profiles extracted from devices. An example how to do that is
# by running `art/tools/boot-image-profile-extract-profile.sh` script.
#
# It is strongly recommended that you make use of extensive critical user journeys flows in order
# to capture the raw boot image profiles described in #3.
#
# NOTE: by default, the script uses default arguments for producing the boot image profiles.
# You might want to adjust the default generation arguments based on the shape of profile
# and based on the metrics that matter for each product.
#
if [[ -z "$ANDROID_BUILD_TOP" ]]; then
echo "You must run on this after running envsetup.sh and launch target"
exit 1
fi
if [[ "$#" -lt 4 ]]; then
echo "Usage $0 <output-dir> <boot.zip-location> <preloaded-denylist-location> <profile-input1> <profile-input2> ... <profman args>"
echo "Without any profman args the script will use defaults."
echo "Example: $0 output-dir boot.zip frameworks/base/config/preloaded-classes-denylist android1.prof android2.prof"
echo " $0 output-dir boot.zip frameworks/base/config/preloaded-classes-denylist android.prof --profman-arg --upgrade-startup-to-hot=true"
echo "preloaded-deny-list-location is usually frameworks/base/config/preloaded-classes-denylist"
exit 1
fi
echo "Creating work dir"
WORK_DIR=/tmp/android-bcp
mkdir -p "$WORK_DIR"
OUT_DIR="$1"
BOOT_ZIP="$2"
PRELOADED_DENYLIST="$3"
shift 3
# Read the profile input args.
profman_profile_input_args=()
boot_image_profman_args=()
system_server_profman_args=()
while [[ "$#" -ge 1 ]]; do
# Read the profman args.
if [[ "$#" -ge 2 ]]; then
if [[ "$1" = '--profman-arg' ]]; then
boot_image_profman_args+=("$2")
system_server_profman_args+=("$2")
shift 2
continue
fi
if [[ "$1" = '--boot-image-profman-arg' ]]; then
boot_image_profman_args+=("$2")
shift 2
continue
fi
if [[ "$1" = '--system-server-profman-arg' ]]; then
system_server_profman_args+=("$2")
shift 2
continue
fi
fi
profman_profile_input_args+=("--profile-file=$1")
shift
done
OUT_BOOT_PROFILE="$OUT_DIR"/boot-image-profile.txt
OUT_PRELOADED_CLASSES="$OUT_DIR"/preloaded-classes
OUT_SYSTEM_SERVER="$OUT_DIR"/art-profile
ART_JARS=("core-oj.jar core-libart.jar okhttp.jar bouncycastle.jar apache-xml.jar")
echo "Changing dirs to the build top"
cd "$ANDROID_BUILD_TOP"
echo "Unziping boot.zip"
BOOT_UNZIP_DIR="$WORK_DIR"/boot-dex
BOOT_JARS="$BOOT_UNZIP_DIR"/dex_bootjars_input
SYSTEM_SERVER_JAR="$BOOT_UNZIP_DIR"/system/framework/services.jar
unzip -o "$BOOT_ZIP" -d "$BOOT_UNZIP_DIR"
echo "Processing boot image jar files"
jar_args=()
for entry in "$BOOT_JARS"/*
do
# Ignore ART jars, since we want fromework related jars only.
jar_name=$(basename "$entry")
if [[ " ${ART_JARS[*]} " != *\ ${jar_name}\ * ]]; then
jar_args+=("--apk=$entry")
fi
done
echo "Running profman for boot image profiles"
# NOTE:
# You might want to adjust the default generation arguments based on the data
# For example, to update the selection thresholds you could specify:
# - For boot image profile:
# --boot-image-profman-arg --method-threshold=10 \
# --boot-image-profman-arg --class-threshold=10 \
# --boot-image-profman-arg --preloaded-class-threshold=10 \
# --boot-image-profman-arg --special-package=android:1 \
# --boot-image-profman-arg --special-package=com.android.systemui:1 \
# - For System Server:
# --system-server-profman-arg --method-threshold=10 \
# --system-server-profman-arg --class-threshold=10 \
# --system-server-profman-arg --special-package=android:1 \
# --system-server-profman-arg --special-package=com.android.systemui:1 \
# You can use --profman-arg to specify the arguments for both boot image
# and system server.
#
# The threshold is percentage of total aggregation, that is, a method/class is
# included in the profile only if it's used by at least x% of the packages.
# (from 0% - include everything to 100% - include only the items that
# are used by all packages on device).
# The --special-package allows you to give a prioriority to certain packages,
# meaning, if the methods is used by that package then the algorithm will use a
# different selection thresholds.
# (system server is identified as the "android" package)
if [[ "${#boot_image_profman_args[*]}" -eq 0 ]]; then
boot_image_profman_args+=("--special-package=android:1")
boot_image_profman_args+=("--special-package=com.android.systemui:1")
fi
boot_image_profman_args+=("${jar_args[@]}")
profman \
--generate-boot-image-profile \
"${profman_profile_input_args[@]}" \
--out-profile-path="$OUT_BOOT_PROFILE" \
--out-preloaded-classes-path="$OUT_PRELOADED_CLASSES" \
--preloaded-classes-denylist="$PRELOADED_DENYLIST" \
"${boot_image_profman_args[@]}"
echo "Done boot image profile"
echo "Running profman for system server"
# We don't have a preloaded-classes nor a denylist files for System Server, so we ignore the arguments.
# We also set the thresholds to 0 to include everything if no args are specified.
if [[ "${#system_server_profman_args[*]}" -eq 0 ]]; then
system_server_profman_args+=("--method-threshold=0")
system_server_profman_args+=("--class-threshold=0")
fi
profman \
--generate-boot-image-profile \
"${profman_profile_input_args[@]}" \
--out-profile-path="$OUT_SYSTEM_SERVER" \
--apk="$SYSTEM_SERVER_JAR" \
"${system_server_profman_args[@]}"
echo "Done system server"
echo ""
echo "Boot profile methods+classes count: $(wc -l $OUT_BOOT_PROFILE)"
echo "Preloaded classes count: $(wc -l $OUT_PRELOADED_CLASSES)"
echo "System server profile methods+classes count: $(wc -l $OUT_SYSTEM_SERVER)"
CLEAN_UP="${CLEAN_UP:-true}"
if [[ "$CLEAN_UP" = "true" ]]; then
rm -rf "$WORK_DIR"
fi
|