Add support for generating boot profiles.

Test: /system/etc/boot-image.bprof is generated
Test: /system/framework/services.bprof is generated
Bug: 119800099
Change-Id: I50f0b665ff104feca4a26dd229625f00013db251
This commit is contained in:
Nicolas Geoffray 2019-07-24 13:19:29 +01:00
parent 2b78fda705
commit e710242b5c
4 changed files with 88 additions and 0 deletions

View File

@ -113,6 +113,7 @@ type ModuleConfig struct {
ProfileClassListing android.OptionalPath
ProfileIsTextListing bool
ProfileBootListing android.OptionalPath
EnforceUsesLibraries bool
PresentOptionalUsesLibraries []string

View File

@ -108,11 +108,15 @@ func GenerateDexpreoptRule(ctx android.PathContext,
rule = android.NewRuleBuilder()
generateProfile := module.ProfileClassListing.Valid() && !global.DisableGenerateProfile
generateBootProfile := module.ProfileBootListing.Valid() && !global.DisableGenerateProfile
var profile android.WritablePath
if generateProfile {
profile = profileCommand(ctx, global, module, rule)
}
if generateBootProfile {
bootProfileCommand(ctx, global, module, rule)
}
if !dexpreoptDisabled(global, module) {
// Don't preopt individual boot jars, they will be preopted together.
@ -190,6 +194,38 @@ func profileCommand(ctx android.PathContext, global GlobalConfig, module ModuleC
return profilePath
}
func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig,
rule *android.RuleBuilder) android.WritablePath {
profilePath := module.BuildPath.InSameDir(ctx, "profile.bprof")
profileInstalledPath := module.DexLocation + ".bprof"
if !module.ProfileIsTextListing {
rule.Command().FlagWithOutput("touch ", profilePath)
}
cmd := rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
Tool(global.Tools.Profman)
// The profile is a test listing of methods.
// We need to generate the actual binary profile.
cmd.FlagWithInput("--create-profile-from=", module.ProfileBootListing.Path())
cmd.
Flag("--generate-boot-profile").
FlagWithInput("--apk=", module.DexPath).
Flag("--dex-location="+module.DexLocation).
FlagWithOutput("--reference-profile-file=", profilePath)
if !module.ProfileIsTextListing {
cmd.Text(fmt.Sprintf(`|| echo "Profile out of date for %s"`, module.DexPath))
}
rule.Install(profilePath, profileInstalledPath)
return profilePath
}
func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder,
arch android.ArchType, profile, bootImage android.Path, bootImageDeps android.Paths, appImage, generateDM bool) {

View File

@ -143,6 +143,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base())
var profileClassListing android.OptionalPath
var profileBootListing android.OptionalPath
profileIsTextListing := false
if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) {
// If dex_preopt.profile_guided is not set, default it based on the existence of the
@ -150,6 +151,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
profileClassListing = android.OptionalPathForPath(
android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile)))
profileBootListing = android.ExistentPathForSource(ctx,
ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot")
profileIsTextListing = true
} else {
profileClassListing = android.ExistentPathForSource(ctx,
@ -169,6 +172,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
ProfileClassListing: profileClassListing,
ProfileIsTextListing: profileIsTextListing,
ProfileBootListing: profileBootListing,
EnforceUsesLibraries: d.enforceUsesLibs,
PresentOptionalUsesLibraries: d.optionalUsesLibs,

View File

@ -216,6 +216,7 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI
}
profile := bootImageProfileRule(ctx, image, missingDeps)
bootFrameworkProfileRule(ctx, image, missingDeps)
var allFiles android.Paths
@ -424,6 +425,52 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin
var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
global := dexpreoptGlobalConfig(ctx)
if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
return nil
}
return ctx.Config().Once(bootFrameworkProfileRuleKey, func() interface{} {
tools := global.Tools
rule := android.NewRuleBuilder()
rule.MissingDeps(missingDeps)
// Some branches like master-art-host don't have frameworks/base, so manually
// handle the case that the default is missing. Those branches won't attempt to build the profile rule,
// and if they do they'll get a missing deps error.
defaultProfile := "frameworks/base/config/boot-profile.txt"
path := android.ExistentPathForSource(ctx, defaultProfile)
var bootFrameworkProfile android.Path
if path.Valid() {
bootFrameworkProfile = path.Path()
} else {
missingDeps = append(missingDeps, defaultProfile)
bootFrameworkProfile = android.PathForOutput(ctx, "missing")
}
profile := image.dir.Join(ctx, "boot.bprof")
rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
Tool(tools.Profman).
Flag("--generate-boot-profile").
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
FlagForEachInput("--apk=", image.dexPaths.Paths()).
FlagForEachArg("--dex-location=", image.dexLocations).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.bprof")
rule.Build(pctx, ctx, "bootFrameworkProfile", "profile boot framework jars")
image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
return profile
}).(android.WritablePath)
}
var bootFrameworkProfileRuleKey = android.NewOnceKey("bootFrameworkProfileRule")
func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
var archs []android.ArchType
for arch := range image.images {