From 7b845e808f07a607a9ecf630eea00a334636f0c5 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Tue, 2 May 2023 14:35:47 +0100 Subject: [PATCH] Generate app profiles even if dexpreopt is disabled. Bug: 280440941 Test: - 1. Patch ag/22302622 to disable dexpreopt. 2. lunch aosp_cf_x86_64_phone-userdebug && m 3. See app profiles still generated. Test: - 1. Patch ag/20592051 to enable profile for service-art. 2. banchan com.android.art x86_64 && m 3. See the profile for service-art generated. Change-Id: I4e721b475b84a2f667bbccc030a8947078f26bb0 --- android/testing.go | 21 +++++++++++++++------ dexpreopt/dexpreopt.go | 8 ++++++++ dexpreopt/testing.go | 7 +++++++ java/dex_test.go | 10 +++++----- java/dexpreopt.go | 10 ++-------- java/dexpreopt_test.go | 25 +++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/android/testing.go b/android/testing.go index fc39a9c7a..2a9c6584e 100644 --- a/android/testing.go +++ b/android/testing.go @@ -813,6 +813,20 @@ func normalizePathRelativeToTop(path Path) Path { return path.RelativeToTop() } +func allOutputs(p BuildParams) []string { + outputs := append(WritablePaths(nil), p.Outputs...) + outputs = append(outputs, p.ImplicitOutputs...) + if p.Output != nil { + outputs = append(outputs, p.Output) + } + return outputs.Strings() +} + +// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms. +func (p TestingBuildParams) AllOutputs() []string { + return allOutputs(p.BuildParams) +} + // baseTestingComponent provides functionality common to both TestingModule and TestingSingleton. type baseTestingComponent struct { config Config @@ -954,12 +968,7 @@ func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildPar func (b baseTestingComponent) allOutputs() []string { var outputFullPaths []string for _, p := range b.provider.BuildParamsForTests() { - outputs := append(WritablePaths(nil), p.Outputs...) - outputs = append(outputs, p.ImplicitOutputs...) - if p.Output != nil { - outputs = append(outputs, p.Output) - } - outputFullPaths = append(outputFullPaths, outputs.Strings()...) + outputFullPaths = append(outputFullPaths, allOutputs(p)...) } return outputFullPaths } diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index a590c72a5..2b38793ff 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -100,11 +100,19 @@ func GenerateDexpreoptRule(ctx android.BuilderContext, globalSoong *GlobalSoongC return rule, nil } +// If dexpreopt is applicable to the module, returns whether dexpreopt is disabled. Otherwise, the +// behavior is undefined. +// When it returns true, dexpreopt artifacts will not be generated, but profile will still be +// generated if profile-guided compilation is requested. func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) bool { if ctx.Config().UnbundledBuild() { return true } + if global.DisablePreopt { + return true + } + if contains(global.DisablePreoptModules, module.Name) { return true } diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go index b3dd3cca2..6ed0736f7 100644 --- a/dexpreopt/testing.go +++ b/dexpreopt/testing.go @@ -181,3 +181,10 @@ func FixtureDisableDexpreoptBootImages(disable bool) android.FixturePreparer { dexpreoptConfig.DisablePreoptBootImages = disable }) } + +// FixtureDisableDexpreopt sets the DisablePreopt property in the global config. +func FixtureDisableDexpreopt(disable bool) android.FixturePreparer { + return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) { + dexpreoptConfig.DisablePreopt = disable + }) +} diff --git a/java/dex_test.go b/java/dex_test.go index 97fc3d0dd..2ba3831f4 100644 --- a/java/dex_test.go +++ b/java/dex_test.go @@ -23,7 +23,7 @@ import ( ) func TestR8(t *testing.T) { - result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, ` + result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` android_app { name: "app", srcs: ["foo.java"], @@ -191,7 +191,7 @@ func TestR8TransitiveDeps(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - fixturePreparer := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd + fixturePreparer := PrepareForTestWithJavaDefaultModules if tc.unbundled { fixturePreparer = android.GroupFixturePreparers( fixturePreparer, @@ -258,7 +258,7 @@ func TestR8TransitiveDeps(t *testing.T) { } func TestR8Flags(t *testing.T) { - result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, ` + result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` android_app { name: "app", srcs: ["foo.java"], @@ -287,7 +287,7 @@ func TestR8Flags(t *testing.T) { } func TestD8(t *testing.T) { - result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, ` + result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` java_library { name: "foo", srcs: ["foo.java"], @@ -328,7 +328,7 @@ func TestD8(t *testing.T) { } func TestProguardFlagsInheritance(t *testing.T) { - result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, ` + result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, ` android_app { name: "app", static_libs: [ diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 0ffedf6c4..f0bb9a32c 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -180,6 +180,8 @@ func moduleName(ctx android.BaseModuleContext) string { return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()) } +// Returns whether dexpreopt is applicable to the module. +// When it returns true, neither profile nor dexpreopt artifacts will be generated. func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { if !ctx.Device() { return true @@ -205,14 +207,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { global := dexpreopt.GetGlobalConfig(ctx) - if global.DisablePreopt { - return true - } - - if inList(moduleName(ctx), global.DisablePreoptModules) { - return true - } - isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) if isApexVariant(ctx) { // Don't preopt APEX variant module unless the module is an APEX system server jar. diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index 3d2c5c3a1..f91ac5cc3 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -438,3 +438,28 @@ func TestAndroidMkEntriesForApex(t *testing.T) { android.AssertIntEquals(t, "entries count", 0, len(entriesList)) } + +func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) { + preparers := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + PrepareForTestWithFakeApexMutator, + dexpreopt.FixtureDisableDexpreopt(true), + ) + + result := preparers.RunTestWithBp(t, ` + java_library { + name: "foo", + installable: true, + dex_preopt: { + profile: "art-profile", + }, + srcs: ["a.java"], + }`) + + ctx := result.TestContext + dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt") + + expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"} + + android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs()) +}