Android S抓取各类profile的方法
- 1. 准备环境
- 2. 开始抓取
- 3. 转换一下profile
1. 准备环境
这是你自己的方法:一般的想法是dex全部限制掉,就算没有限制掉的也只做默认quicken模式, 在build里面找设置compilerFilter所有的地方都变了,有多少
(有些不需要修改,也可以参考Google这里只提供一般的伪代码思路)
1、build/make/target/product/runtime_libart.mk
中间修改,增加以下修改
//build/make/target/product/runtime_libart.mk PRODUCT_SYSTEM_PROPERTIES = \ dalvik.vm.profilesystemserver=true \ dalvik.vm.profilebootclasspath=true
2、art代码修改(这是以前的修改,现在不需要了,可以操作1)
--- a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc @@ -429,14 429,17 @@ class ProfileSaver::GetClassesAndMethodsHelper {
static uint32_t CalculateHotMethodSampleThreshold(bool startup, const ProfileSaverOptions& options) {
Runtime* runtime = Runtime::Current(); //yunhen change if (startup) {
} //if (startup) {
const bool is_low_ram = runtime->GetHeap()->IsLowMemoryMode(); return options.GetHotStartupMethodSamples(is_low_ram); - } else if (runtime->() != nullptr) {
- return runtime->GetJit()->WarmMethodThreshold(); - } else {
- return std::numeric_limits<uint32_t>::max(); - } + //} else if (runtime->GetJit() != nullptr) {
+ // return runtime->GetJit()->WarmMethodThreshold(); + //} else {
+ // return std::numeric_limits<uint32_t>::max(); + //} } //直接手动修改art,profile_boot_class_path_,效果和设置属性值一样的意思 --- a/runtime/jit/profile_saver_options.h +++ b/runtime/jit/profile_saver_options.h @@ -34,6 +34,7 @@ struct ProfileSaverOptions {
static constexpr uint32_t kMaxNotificationBeforeWake = 50; static constexpr uint32_t kHotStartupMethodSamplesNotSet = std::numeric_limits<uint32_t>::max(); +//yunhen change ProfileSaverOptions() : enabled_(false), min_save_period_ms_(kMinSavePeriodMs), @@ -45,7 +46,7 @@ struct ProfileSaverOptions {
min_notification_before_wake_(kMinNotificationBeforeWake), max_notification_before_wake_(kMaxNotificationBeforeWake), profile_path_(""), - profile_boot_class_path_(false), + profile_boot_class_path_(true), profile_aot_code_(false), wait_for_jit_notifications_to_save_(true) {
} @@ -116,7 +117,7 @@ struct ProfileSaverOptions {
return profile_path_; } bool GetProfileBootClassPath() const {
- return profile_boot_class_path_; + return true;//yunhen change }
3、在build/make/target/product/目录搜索PRODUCT_SYSTEM_SERVER_COMPILER_FILTER相关,将speed-profile改成quicken
-PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := speed-profile
+PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := quicken
4、在dex_preopt_config.mk中disable preopt
build/make/core/dex_preopt_config.mk
-ENABLE_PREOPT := true
-ENABLE_PREOPT_BOOT_IMAGES := true
+ENABLE_PREOPT := false
+ENABLE_PREOPT_BOOT_IMAGES := false
# Global switch to control if updatable boot jars are included in dexpreopt.
DEX_PREOPT_WITH_UPDATABLE_BCP := true
+WITH_DEXPREOPT_BOOT_IMG_AND_SYSTEM_SERVER_ONLY ?= true
# Conditional to building on linux, as dex2oat currently does not work on darwin.
```java
5、board_config.mk中将全部dex去掉WITH_DEXPREOPT,不做编译的dex了
```java
//build/make/core/board_config.mk
ifeq ($(HOST_OS),linux)
WITH_DEXPREOPT := true
endif
+
+WITH_DEXPREOPT := false
+
# ###############################################################
# Broken build defaults
6、将dex预编译时走的build/soong/dexpreopt/dexpreopt.go
全部修改成quicken,宁可错杀不可放过 build/soong/dexpreopt/dexpreopt.go
//build/soong/dexpreopt/dexpreopt.go
if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
var compilerFilter string
if global.SystemServerJars.ContainsJar(module.Name) {
// Jars of system server, use the product option if it is set, speed otherwise.
if global.SystemServerCompilerFilter != "" {
- compilerFilter = global.SystemServerCompilerFilter
+ //compilerFilter = global.SystemServerCompilerFilter
+ compilerFilter = "quicken"
} else {
- compilerFilter = "speed"
+ //compilerFilter = "speed"
+ compilerFilter = "quicken"
}
} else if contains(global.SpeedApps, module.Name) || contains(global.SystemServerApps, module.Name) {
// Apps loaded into system server, and apps the product default to being compiled with the
// 'speed' compiler filter.
- compilerFilter = "speed"
+ //compilerFilter = "speed"
+ compilerFilter = "quicken"
} else if profile != nil {
// For non system server jars, use speed-profile when we have a profile.
- compilerFilter = "speed-profile"
+ //compilerFilter = "speed-profile"
+ compilerFilter = "quicken"
} else if global.DefaultCompilerFilter != "" {
- compilerFilter = global.DefaultCompilerFilter
+ //compilerFilter = global.DefaultCompilerFilter
+ compilerFilter = "quicken"
} else {
compilerFilter = "quicken"
}
7、将下面几个文件全部清空,源码中定义system_server和bootimage的全部去掉
frameworks/base/config/
frameworks/base/config/boot-profile.txt
frameworks/base/config/boot-image-profile.txt
frameworks/base/config/preloaded-classes
frameworks/base/services/art-profile
frameworks/base/services/art-profile-boot
注释掉frameworks/base/services/Android.bp中art-profile、dex_preopt相关设置
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -83,10 +83,10 @@ java_library {
name: "services",
installable: true,
- dex_preopt: {
- app_image: true,
- profile: "art-profile",
- },
+ //dex_preopt: {
+ // app_image: true,
+ // profile: "art-profile",
+ //},
srcs: [":services-main-sources"],
@@ -169,10 +169,10 @@ platform_compat_config {
src: ":services",
}
-filegroup {
- name: "art-profile",
- srcs: ["art-profile"],
-}
+//filegroup {
+// name: "art-profile",
+// srcs: ["art-profile"],
+//}
8、如果出问题,调试为了调试art做准备,现将partner_modules中GMS的art做掉
partner_modules/ArtPrebuilt/Android.bp => 重命名partner_modules/ArtPrebuilt/Android.bp.bak
build/mainline_modules_s.mk注释掉Google art的编译
# Art
-MAINLINE_COMPRESS_APEX_ART ?= true
-ifeq ($(MAINLINE_COMPRESS_APEX_ART),true)
-PRODUCT_PACKAGES += \
- com.google.android.art_compressed
-else
-PRODUCT_PACKAGES += \
- com.google.android.art
-endif
+#MAINLINE_COMPRESS_APEX_ART ?= true
+#ifeq ($(MAINLINE_COMPRESS_APEX_ART),true)
+#PRODUCT_PACKAGES += \
+# com.google.android.art_compressed
+#else
+#PRODUCT_PACKAGES += \
+# com.google.android.art
+#endif
2. 开始抓取
修改了上一章节的代码后,编译,开机抓取。
模拟手机操作(这个大家可以随意,我这里是相对简单的操作,但不一定是最好的) 1、开机后,进入桌面,屏幕设置成常亮(避免出现bg dex):adb shell wm dismiss-keyguard; adb shell svc power stayon true
2、正常操作手机,稍微点击一下常用的应用
3、执行monkey 40-50分钟 adb shell monkey --throttle 300 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -s 1000 -v -v -v 30000 1
5、执行monkey 40-50分钟 adb shell monkey --throttle 300 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -s 1000 -v -v -v 30000 1
6、将/data/misc/profiles/cur/0的内容全部pull出来
里面android目录就是system_server,其它都是以模块包名形式抓取类似下面形式
144K ./android/primary.prof
148K ./android
100K ./com.android.chrome/primary.prof
104K ./com.android.chrome
116K ./com.android.systemui/primary.prof
120K ./com.android.systemui
84K ./com.android.settings/primary.prof
88K ./com.android.settings
3. 转换一下profile
抓取的上述profile其实是可以直接预置进入设备中去的,不过也可以参考Android的做法,转换一下, 将profile文件转换成方法和类
1、system_server的profile转换,可以参考下面指令
profman \
--generate-boot-image-profile \
"${profman_profile_input_args[@]}" \
--out-profile-path="$OUT_SYSTEM_SERVER" \
--apk="$SYSTEM_SERVER_JAR" \
--method-threshold=0 \
--class-threshold=0
例如
./prebuilts/module_sdk/art/current/host-exports/x86_64/bin/profman --generate-boot-image-profile --profile-file=./android/primary.prof --out-profile-path=SystemServer.art-profile --apk=com.android.location.provider.jar --apk=services.jar (…很多–apk) --method-threshold=0 --class-threshold=0
–apk=就是所有的PRODUCT_SYSTEM_SERVER_JARS都包含进去
2、boot image protfile的转换,由于这个是zygote加载时载入,包含在所有上层进程中,所以是需要加入所有的prof文件
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" \
--special-package=android:1 \
--special-package=com.android.systemui:1 \
"${profman_args[@]}"
实际执行指令类似下面:
./prebuilts/module_sdk/art/current/host-exports/x86_64/bin/profman --generate-boot-image-protfile --profile-file=./android/primary.prof --profile-file=/soong/ssi/dex_artjars_input,out*/soong/*ssi/dex_bootjars_input都包含进去
3、抓取所有内置应用的profile文件
如Settings的profile的抓取
packageName=com.android.settings;packageModule=Settings;/source/prebuilts/module_sdk/art/current/host-exports/x86_64/bin/profman --reference-profile-file=./ p a c k a g e N a m e / p r i m a r y . p r o f − − d u m p − c l a s s e s − a n d − m e t h o d s − − a p k = {packageName}/primary.prof --dump-classes-and-methods --apk= packageName/primary.prof−−dump−classes−and−methods−−apk={packageModule}.apk --dex-location=${packageModule}.apk > ${packageModule}.art-profile
ps: --apk=${packageModule}.apk其实就是–apk=Settings.apk,指定apk的位置