当前位置:   article > 正文

Android S抓取各类profile的方法_systemservercompilerfilter

systemservercompilerfilter

Android S抓取各类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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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->GetJit() != 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
   }

  • 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

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
  • 1
  • 2

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

  • 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

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"
                }
  • 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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注释掉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"],
+//}

  • 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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

4、继续操作一下手机的基本操作

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

例如

./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[@]}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

实际执行指令类似下面:

./prebuilts/module_sdk/art/current/host-exports/x86_64/bin/profman --generate-boot-image-protfile --profile-file=./android/primary.prof --profile-file=(所有抓取到的profile一个个加进去,可以用Google脚本) --out-profile-path=boot-image-profile.txt --out-preloaded-classes-path=preloaded-classes -preloaded-classes-denylist=preloaded-classes-denylist(frameworks/base/config/源码里面的) --special-package=android:1 --special-package=com.android.systemui:1 --apk=就是所有的out/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.profdumpclassesandmethodsapk={packageModule}.apk --dex-location=${packageModule}.apk > ${packageModule}.art-profile

ps: --apk=${packageModule}.apk其实就是–apk=Settings.apk,指定apk的位置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/602000
推荐阅读
相关标签
  

闽ICP备14008679号