Use the profiles in the APEX to dexpreopt system server jars.
After this change, if "profile_guided: true" is set, profile-guided compilation will be enabled for the jar and the ".prof" file next to the jar in the APEX ("javalib/<name>.jar.prof") will be used as the profile when dexpreopting for the prebuilt APEX. Bug: 241823638 Test: m nothing Test: - 1. (on internal master) Patch aosp/2426453. 2. Build the APEX bundle and the module SDK of com.android.wifi 3. (on tm-dev) Patch this CL and aosp/2141972. 4. Copy the APEX bundle and the module SDK built on step 2 to the source tree 5. Disable hiddenapi check 6. lunch cf_x86_64_phone-userdebug && m MODULE_BUILD_FROM_SOURCE=false com.google.android.wifi 7. cat out/soong/.intermediates/prebuilts/module_sdk/Wifi/current/prebuilt_service-wifi/android_common_com.android.wifi/dexpreopt/oat/x86_64/javalib.invocation 8. See the profile being used. Change-Id: I55a5a295e9c5d6f0564afb139c5fb7da91ab8cae
This commit is contained in:
@@ -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"
|
||||
|
@@ -222,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",
|
||||
@@ -245,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",
|
||||
@@ -257,15 +269,27 @@ 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) {
|
||||
@@ -354,7 +378,7 @@ 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",
|
||||
@@ -377,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",
|
||||
@@ -389,10 +425,22 @@ 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) {
|
||||
|
@@ -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 {
|
||||
@@ -106,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 {
|
||||
@@ -308,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) != "" {
|
||||
@@ -389,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 {
|
||||
@@ -431,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
|
||||
}
|
||||
|
21
java/java.go
21
java/java.go
@@ -2002,7 +2002,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()))
|
||||
@@ -2011,6 +2012,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.
|
||||
@@ -2145,11 +2151,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
|
||||
@@ -2162,7 +2173,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
|
||||
|
@@ -2445,18 +2445,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
|
||||
@@ -2585,7 +2591,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
|
||||
|
Reference in New Issue
Block a user