1. Prepare the environment
Here we are talking about our own method: the general idea is to limit all dex. Even if there is no limit, only the default quicken mode is used,
Find the place where the compilerFilter is set in the build. All of them have been changed. How much is there
(some parts do not need to be modified. You can also refer to Google's methods. Here is just a general idea of pseudo code)
1,build/make/target/product/runtime_libart.mk, add the following modifications
//build/make/target/product/runtime_libart.mk PRODUCT_SYSTEM_PROPERTIES += \ dalvik.vm.profilesystemserver=true \ dalvik.vm.profilebootclasspath=true
2. art code modification (this is a previous modification. It is unnecessary now. Operation 1 is OK)
--- 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(); + //} } //Modify art and profile directly and manually_ boot_ class_ path_, The effect has the same meaning as setting the attribute value --- 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. Search the build/make/target/product / directory for PRODUCT_SYSTEM_SERVER_COMPILER_FILTER related, change speed profile to quicken
-PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := speed-profile +PRODUCT_SYSTEM_SERVER_COMPILER_FILTER := quicken
4. In dex_ preopt_ disable preopt in config.mk
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 Lieutenant general all dex Remove WITH_DEXPREOPT,No compilation dex Yes ```java //build/make/core/board_config.mk ifeq ($(HOST_OS),linux) WITH_DEXPREOPT := true endif + +WITH_DEXPREOPT := false + # ############################################################### # Broken build defaults
6. Modify the build/soong/dexpreopt/dexpreopt.go used during dex precompiling to quicken. It's better to kill by mistake than to let go
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. Empty all the following files and define system in the source code_ Remove all of server and 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
Comment out art profile and Dex in frameworks/base/services/Android.bp_ Preopt related settings
--- 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. If something goes wrong, debug. In order to prepare for debugging art, now turn to partner_ GMS art in modules is deleted
partner_ Modules / artprebuilt / Android. BP = > rename partner_modules/ArtPrebuilt/Android.bp.bak
build/mainline_modules_s.mk comment out the compilation of 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. Start grabbing
After modifying the code in the previous chapter, compile, boot and grab.
Simulate mobile phone operation (you can do this at will. Here is a relatively simple operation, but it is not necessarily the best)
1. After startup, enter the desktop and set the screen to be always on (avoid bg dex): ADB shell WM disass keyguard; adb shell svc power stayon true
2. Operate the mobile phone normally and click the commonly used application a little
3. Execute monkey for 40-50 minutes
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. Continue to operate the basic operation of the mobile phone
5. Execute monkey for 40-50 minutes
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. pull all the contents of / data/misc/profiles/cur/0
The android directory is system_server, others are captured in the form of module package name, similar to the following form
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. Change the profile
In fact, the above captured profile s can be preset directly into the device, but you can also refer to the practice of Android and convert them,
Convert profile files to methods and classes
1,system_ For the profile conversion of server, refer to the following instructions
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
for example
./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 (... Many – APK) -- Method threshold = 0 -- class threshold = 0
– apk = all products_ SYSTEM_ SERVER_ Jars is included
2. The conversion of boot image protfile is loaded when zygote is loaded and included in all upper processes, so all prof files need to be added
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[@]}"
The actual execution instructions are similar to the following:
./prebuilts/module_ sdk/art/current/host-exports/x86_ 64 / bin / profiman -- generate boot image Protfile -- profile file =. / Android / primary. Prof -- profile file = (all captured profiles can be added one by one, and Google script can be used) -- out profile path = boot image profile.txt -- out preloaded classes path = preloaded classes - preloaded classes Denylist = preloaded classes Denylist (in the framework / base / config / source code) -- special package = Android: 1 -- special package = com. Android. Systemui: 1 -- APK = includes all out/soong/ssi/dex_artjars_input, out*/soong/*ssi/dex_bootjars_input
3. Grab the profile files of all built-in applications
Such as capturing the profile of Settings
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 is actually – apk=Settings.apk, specifying the location of APK