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:
parent
2b78fda705
commit
e710242b5c
|
@ -113,6 +113,7 @@ type ModuleConfig struct {
|
||||||
|
|
||||||
ProfileClassListing android.OptionalPath
|
ProfileClassListing android.OptionalPath
|
||||||
ProfileIsTextListing bool
|
ProfileIsTextListing bool
|
||||||
|
ProfileBootListing android.OptionalPath
|
||||||
|
|
||||||
EnforceUsesLibraries bool
|
EnforceUsesLibraries bool
|
||||||
PresentOptionalUsesLibraries []string
|
PresentOptionalUsesLibraries []string
|
||||||
|
|
|
@ -108,11 +108,15 @@ func GenerateDexpreoptRule(ctx android.PathContext,
|
||||||
rule = android.NewRuleBuilder()
|
rule = android.NewRuleBuilder()
|
||||||
|
|
||||||
generateProfile := module.ProfileClassListing.Valid() && !global.DisableGenerateProfile
|
generateProfile := module.ProfileClassListing.Valid() && !global.DisableGenerateProfile
|
||||||
|
generateBootProfile := module.ProfileBootListing.Valid() && !global.DisableGenerateProfile
|
||||||
|
|
||||||
var profile android.WritablePath
|
var profile android.WritablePath
|
||||||
if generateProfile {
|
if generateProfile {
|
||||||
profile = profileCommand(ctx, global, module, rule)
|
profile = profileCommand(ctx, global, module, rule)
|
||||||
}
|
}
|
||||||
|
if generateBootProfile {
|
||||||
|
bootProfileCommand(ctx, global, module, rule)
|
||||||
|
}
|
||||||
|
|
||||||
if !dexpreoptDisabled(global, module) {
|
if !dexpreoptDisabled(global, module) {
|
||||||
// Don't preopt individual boot jars, they will be preopted together.
|
// 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
|
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,
|
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) {
|
arch android.ArchType, profile, bootImage android.Path, bootImageDeps android.Paths, appImage, generateDM bool) {
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
||||||
strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base())
|
strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base())
|
||||||
|
|
||||||
var profileClassListing android.OptionalPath
|
var profileClassListing android.OptionalPath
|
||||||
|
var profileBootListing android.OptionalPath
|
||||||
profileIsTextListing := false
|
profileIsTextListing := false
|
||||||
if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) {
|
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
|
// 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) != "" {
|
if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
|
||||||
profileClassListing = android.OptionalPathForPath(
|
profileClassListing = android.OptionalPathForPath(
|
||||||
android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile)))
|
android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile)))
|
||||||
|
profileBootListing = android.ExistentPathForSource(ctx,
|
||||||
|
ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot")
|
||||||
profileIsTextListing = true
|
profileIsTextListing = true
|
||||||
} else {
|
} else {
|
||||||
profileClassListing = android.ExistentPathForSource(ctx,
|
profileClassListing = android.ExistentPathForSource(ctx,
|
||||||
|
@ -169,6 +172,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
||||||
|
|
||||||
ProfileClassListing: profileClassListing,
|
ProfileClassListing: profileClassListing,
|
||||||
ProfileIsTextListing: profileIsTextListing,
|
ProfileIsTextListing: profileIsTextListing,
|
||||||
|
ProfileBootListing: profileBootListing,
|
||||||
|
|
||||||
EnforceUsesLibraries: d.enforceUsesLibs,
|
EnforceUsesLibraries: d.enforceUsesLibs,
|
||||||
PresentOptionalUsesLibraries: d.optionalUsesLibs,
|
PresentOptionalUsesLibraries: d.optionalUsesLibs,
|
||||||
|
|
|
@ -216,6 +216,7 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI
|
||||||
}
|
}
|
||||||
|
|
||||||
profile := bootImageProfileRule(ctx, image, missingDeps)
|
profile := bootImageProfileRule(ctx, image, missingDeps)
|
||||||
|
bootFrameworkProfileRule(ctx, image, missingDeps)
|
||||||
|
|
||||||
var allFiles android.Paths
|
var allFiles android.Paths
|
||||||
|
|
||||||
|
@ -424,6 +425,52 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin
|
||||||
|
|
||||||
var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
|
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) {
|
func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
|
||||||
var archs []android.ArchType
|
var archs []android.ArchType
|
||||||
for arch := range image.images {
|
for arch := range image.images {
|
||||||
|
|
Loading…
Reference in New Issue