Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c004bf3b authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I55a5a295,I9c09451d,I05177388

* changes:
  Use the profiles in the APEX to dexpreopt system server jars.
  Add tests for the ignored "profile_guided: true" property.
  Output dex_preopt to SDK snapshot.
parents ec8f7543 81e46817
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1769,7 +1769,7 @@ func apexFileForJavaModuleWithFile(ctx android.BaseModuleContext, module javaMod

func apexFileForJavaModuleProfile(ctx android.BaseModuleContext, module javaModule) *apexFile {
	if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
		if profilePathOnHost := dexpreopter.ProfilePathOnHost(); profilePathOnHost != nil {
		if profilePathOnHost := dexpreopter.OutputProfilePathOnHost(); profilePathOnHost != nil {
			dirInApex := "javalib"
			af := newApexFile(ctx, profilePathOnHost, module.BaseModuleName()+"-profile", dirInApex, etc, nil)
			af.customStem = module.Stem() + ".jar.prof"
+108 −11
Original line number Diff line number Diff line
@@ -15,10 +15,11 @@
package apex

import (
	"android/soong/dexpreopt"
	"strings"
	"testing"

	"android/soong/android"
	"android/soong/dexpreopt"
	"android/soong/java"
)

@@ -31,7 +32,7 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithSystemserverclasspathFragment,
		prepareForTestWithMyapex,
		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar"),
		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"),
	).RunTestWithBp(t, `
		apex {
			name: "myapex",
@@ -69,11 +70,24 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
			],
		}

		java_library {
			name: "baz",
			srcs: ["d.java"],
			installable: true,
			dex_preopt: {
				profile_guided: true, // ignored
			},
			apex_available: [
				"myapex",
			],
		}

		systemserverclasspath_fragment {
			name: "mysystemserverclasspathfragment",
			contents: [
				"foo",
				"bar",
				"baz",
			],
			apex_available: [
				"myapex",
@@ -81,17 +95,24 @@ func TestSystemserverclasspathFragmentContents(t *testing.T) {
		}
	`)

	ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
	ctx := result.TestContext

	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"etc/classpaths/systemserverclasspath.pb",
		"javalib/foo.jar",
		"javalib/bar.jar",
		"javalib/bar.jar.prof",
		"javalib/baz.jar",
	})

	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
	java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex_image", []string{
		`myapex.key`,
		`mysystemserverclasspathfragment`,
	})

	assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false)
	assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true)
	assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false)
}

func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) {
@@ -201,7 +222,7 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithSystemserverclasspathFragment,
		prepareForTestWithMyapex,
		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo", "myapex:bar"),
	).RunTestWithBp(t, `
		prebuilt_apex {
			name: "myapex",
@@ -224,11 +245,23 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
			],
		}

		java_import {
			name: "bar",
			jars: ["bar.jar"],
			dex_preopt: {
				profile_guided: true,
			},
			apex_available: [
				"myapex",
			],
		}

		prebuilt_systemserverclasspath_fragment {
			name: "mysystemserverclasspathfragment",
			prefer: true,
			contents: [
				"foo",
				"bar",
			],
			apex_available: [
				"myapex",
@@ -236,22 +269,34 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
		}
	`)

	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
	ctx := result.TestContext

	java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
		`myapex.apex.selector`,
		`prebuilt_mysystemserverclasspathfragment`,
	})

	java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
	java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
		`myapex.deapexer`,
		`prebuilt_bar`,
		`prebuilt_foo`,
	})

	ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
		"javalib/foo.jar",
		"javalib/bar.jar",
		"javalib/bar.jar.prof",
	})

	assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
	assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
}

func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithSystemserverclasspathFragment,
		prepareForTestWithMyapex,
		dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar"),
		dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar", "myapex:baz"),
	).RunTestWithBp(t, `
		apex {
			name: "myapex",
@@ -289,11 +334,24 @@ func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
			],
		}

		java_library {
			name: "baz",
			srcs: ["d.java"],
			dex_preopt: {
				profile_guided: true, // ignored
			},
			installable: true,
			apex_available: [
				"myapex",
			],
		}

		systemserverclasspath_fragment {
			name: "mysystemserverclasspathfragment",
			standalone_contents: [
				"foo",
				"bar",
				"baz",
			],
			apex_available: [
				"myapex",
@@ -301,19 +359,26 @@ func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
		}
	`)

	ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
	ctx := result.TestContext

	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"etc/classpaths/systemserverclasspath.pb",
		"javalib/foo.jar",
		"javalib/bar.jar",
		"javalib/bar.jar.prof",
		"javalib/baz.jar",
	})

	assertProfileGuided(t, ctx, "foo", "android_common_apex10000", false)
	assertProfileGuided(t, ctx, "bar", "android_common_apex10000", true)
	assertProfileGuided(t, ctx, "baz", "android_common_apex10000", false)
}

func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
	result := android.GroupFixturePreparers(
		prepareForTestWithSystemserverclasspathFragment,
		prepareForTestWithMyapex,
		dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo"),
		dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo", "myapex:bar"),
	).RunTestWithBp(t, `
		prebuilt_apex {
			name: "myapex",
@@ -336,11 +401,23 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
			],
		}

		java_import {
			name: "bar",
			jars: ["bar.jar"],
			dex_preopt: {
				profile_guided: true,
			},
			apex_available: [
				"myapex",
			],
		}

		prebuilt_systemserverclasspath_fragment {
			name: "mysystemserverclasspathfragment",
			prefer: true,
			standalone_contents: [
				"foo",
				"bar",
			],
			apex_available: [
				"myapex",
@@ -348,8 +425,28 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
		}
	`)

	java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
	ctx := result.TestContext

	java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{
		`myapex.deapexer`,
		`prebuilt_bar`,
		`prebuilt_foo`,
	})

	ensureExactDeapexedContents(t, ctx, "myapex", "android_common", []string{
		"javalib/foo.jar",
		"javalib/bar.jar",
		"javalib/bar.jar.prof",
	})

	assertProfileGuided(t, ctx, "foo", "android_common_myapex", false)
	assertProfileGuided(t, ctx, "bar", "android_common_myapex", true)
}

func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName string, variant string, expected bool) {
	dexpreopt := ctx.ModuleForTests(moduleName, variant).Rule("dexpreopt")
	actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=")
	if expected != actual {
		t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual)
	}
}
+44 −9
Original line number Diff line number Diff line
@@ -23,11 +23,24 @@ import (
)

type DexpreopterInterface interface {
	IsInstallable() bool // Structs that embed dexpreopter must implement this.
	// True if the java module is to be dexed and installed on devices.
	// Structs that embed dexpreopter must implement this.
	IsInstallable() bool

	// True if dexpreopt is disabled for the java module.
	dexpreoptDisabled(ctx android.BaseModuleContext) bool

	// If the java module is to be installed into an APEX, this list contains information about the
	// dexpreopt outputs to be installed on devices. Note that these dexpreopt outputs are installed
	// outside of the APEX.
	DexpreoptBuiltInstalledForApex() []dexpreopterInstall

	// The Make entries to install the dexpreopt outputs. Derived from
	// `DexpreoptBuiltInstalledForApex`.
	AndroidMkEntriesForApex() []android.AndroidMkEntries
	ProfilePathOnHost() android.Path

	// See `dexpreopter.outputProfilePathOnHost`.
	OutputProfilePathOnHost() android.Path
}

type dexpreopterInstall struct {
@@ -79,6 +92,7 @@ func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries {

type dexpreopter struct {
	dexpreoptProperties       DexpreoptProperties
	importDexpreoptProperties ImportDexpreoptProperties

	installPath         android.InstallPath
	uncompressedDex     bool
@@ -105,8 +119,13 @@ type dexpreopter struct {
	//   dexpreopt another partition).
	configPath android.WritablePath

	// The path to the profile on host.
	profilePathOnHost android.Path
	// The path to the profile on host that dexpreopter generates. This is used as the input for
	// dex2oat.
	outputProfilePathOnHost android.Path

	// The path to the profile that dexpreopter accepts. It must be in the binary format. If this is
	// set, it overrides the profile settings in `dexpreoptProperties`.
	inputProfilePathOnHost android.Path
}

type DexpreoptProperties struct {
@@ -127,6 +146,18 @@ type DexpreoptProperties struct {
		// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
		Profile *string `android:"path"`
	}

	Dex_preopt_result struct {
		// True if profile-guided optimization is actually enabled.
		Profile_guided bool
	} `blueprint:"mutated"`
}

type ImportDexpreoptProperties struct {
	Dex_preopt struct {
		// If true, use the profile in the prebuilt APEX to guide optimization. Defaults to false.
		Profile_guided *bool
	}
}

func init() {
@@ -295,7 +326,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
	var profileClassListing android.OptionalPath
	var profileBootListing android.OptionalPath
	profileIsTextListing := false
	if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) {
	if d.inputProfilePathOnHost != nil {
		profileClassListing = android.OptionalPathForPath(d.inputProfilePathOnHost)
	} else if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) && !forPrebuiltApex(ctx) {
		// If dex_preopt.profile_guided is not set, default it based on the existence of the
		// dexprepot.profile option or the profile class listing.
		if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
@@ -310,6 +343,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
		}
	}

	d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid()

	// Full dexpreopt config, used to create dexpreopt build rules.
	dexpreoptConfig := &dexpreopt.ModuleConfig{
		Name:            moduleName(ctx),
@@ -374,7 +409,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
		isProfile := strings.HasSuffix(installBase, ".prof")

		if isProfile {
			d.profilePathOnHost = install.From
			d.outputProfilePathOnHost = install.From
		}

		if isApexSystemServerJar {
@@ -416,6 +451,6 @@ func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
	return entries
}

func (d *dexpreopter) ProfilePathOnHost() android.Path {
	return d.profilePathOnHost
func (d *dexpreopter) OutputProfilePathOnHost() android.Path {
	return d.outputProfilePathOnHost
}
+28 −5
Original line number Diff line number Diff line
@@ -801,6 +801,8 @@ type librarySdkMemberProperties struct {

	// The value of the min_sdk_version property, translated into a number where possible.
	MinSdkVersion *string `supported_build_releases:"Tiramisu+"`

	DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
}

func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -818,6 +820,10 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo
		canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.ApiLevel.String())
		p.MinSdkVersion = proptools.StringPtr(canonical)
	}

	if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
		p.DexPreoptProfileGuided = proptools.BoolPtr(true)
	}
}

func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -844,6 +850,11 @@ func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberConte
		propertySet.AddProperty("permitted_packages", p.PermittedPackages)
	}

	dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
	if p.DexPreoptProfileGuided != nil {
		dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided))
	}

	// Do not copy anything else to the snapshot.
	if memberType.onlyCopyJarToSnapshot {
		return
@@ -2014,7 +2025,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
			if di == nil {
				return // An error has been reported by FindDeapexerProviderForModule.
			}
			if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
			dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName())
			if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
				dexJarFile := makeDexJarPathFromPath(dexOutputPath)
				j.dexJarFile = dexJarFile
				installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
@@ -2023,6 +2035,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
				setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
				j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex

				if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
					j.dexpreopter.inputProfilePathOnHost = profilePath
				}

				j.dexpreopt(ctx, dexOutputPath)

				// Initialize the hiddenapi structure.
@@ -2157,11 +2174,16 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or
// java_sdk_library_import with the specified base module name requires to be exported from a
// prebuilt_apex/apex_set.
func requiredFilesFromPrebuiltApexForImport(name string) []string {
func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string {
	dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name)
	// Add the dex implementation jar to the set of exported files.
	return []string{
		apexRootRelativePathToJavaLib(name),
	files := []string{
		dexJarFileApexRootRelative,
	}
	if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) {
		files = append(files, dexJarFileApexRootRelative+".prof")
	}
	return files
}

// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for
@@ -2174,7 +2196,7 @@ var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil)

func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string {
	name := j.BaseModuleName()
	return requiredFilesFromPrebuiltApexForImport(name)
	return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter)
}

// Add compile time check for interface implementation
@@ -2215,6 +2237,7 @@ func ImportFactory() android.Module {
	module.AddProperties(
		&module.properties,
		&module.dexer.dexProperties,
		&module.importDexpreoptProperties,
	)

	module.initModuleAndImport(module)
+21 −5
Original line number Diff line number Diff line
@@ -2243,7 +2243,7 @@ func sdkLibraryImportFactory() android.Module {

	allScopeProperties, scopeToProperties := createPropertiesInstance()
	module.scopeProperties = scopeToProperties
	module.AddProperties(&module.properties, allScopeProperties)
	module.AddProperties(&module.properties, allScopeProperties, &module.importDexpreoptProperties)

	// Initialize information common between source and prebuilt.
	module.initCommon(module)
@@ -2487,18 +2487,24 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
			if di == nil {
				return // An error has been reported by FindDeapexerProviderForModule.
			}
			if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
			dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName())
			if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
				dexJarFile := makeDexJarPathFromPath(dexOutputPath)
				module.dexJarFile = dexJarFile
				installPath := android.PathForModuleInPartitionInstall(
					ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
					ctx, "apex", ai.ApexVariationName, dexJarFileApexRootRelative)
				module.installFile = installPath
				module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)

				// Dexpreopting.
				module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
				module.dexpreopter.isSDKLibrary = true
				module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &module.dexpreopter)

				if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
					module.dexpreopter.inputProfilePathOnHost = profilePath
				}

				// Dexpreopting.
				module.dexpreopt(ctx, dexOutputPath)
			} else {
				// This should never happen as a variant for a prebuilt_apex is only created if the
@@ -2627,7 +2633,7 @@ var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil)

func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
	name := module.BaseModuleName()
	return requiredFilesFromPrebuiltApexForImport(name)
	return requiredFilesFromPrebuiltApexForImport(name, &module.dexpreopter)
}

// java_sdk_library_xml
@@ -3036,6 +3042,8 @@ type sdkLibrarySdkMemberProperties struct {
	//
	// This means that the device won't recognise this library as installed.
	Max_device_sdk *string

	DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"`
}

type scopeProperties struct {
@@ -3089,6 +3097,10 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
	s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before
	s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
	s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk

	if sdk.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided {
		s.DexPreoptProfileGuided = proptools.BoolPtr(true)
	}
}

func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -3104,6 +3116,10 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo
	if len(s.Permitted_packages) > 0 {
		propertySet.AddProperty("permitted_packages", s.Permitted_packages)
	}
	dexPreoptSet := propertySet.AddPropertySet("dex_preopt")
	if s.DexPreoptProfileGuided != nil {
		dexPreoptSet.AddProperty("profile_guided", proptools.Bool(s.DexPreoptProfileGuided))
	}

	stem := s.Stem

Loading