Remove profilePathOnHost from bootImageConfig

The use of this field to return information from bootImageProfileRule
up the call stack to one of the users resulted in data races being
detected. This change simply returns the profile path back up the call
stack.

Bug: 245956352
Test: m nothing
      go test -race ./sdk/... -run TestSnapshotWithBootclasspathFragment_ImageName -test.count 100
      # Run the previous command without this change and sometimes it
      # shows the data race around profilePathOnHost. With this change
      # that data race is not reported. Although there is still another
      # data race.
Change-Id: I03b09e514cc94f2a6c9d5117d3b2f130cc2e4f5b
This commit is contained in:
Paul Duffin 2022-10-04 15:36:44 +01:00
parent a8df7e1c5b
commit 9f6ac0bb42
3 changed files with 42 additions and 33 deletions

View file

@ -264,7 +264,7 @@ type commonBootclasspathFragment interface {
// //
// If it could not create the files then it will return nil. Otherwise, it will return a map from // If it could not create the files then it will return nil. Otherwise, it will return a map from
// android.ArchType to the predefined paths of the boot image files. // android.ArchType to the predefined paths of the boot image files.
produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs
} }
var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil) var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
@ -583,16 +583,16 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Perform hidden API processing. // Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments) hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
var bootImageFilesByArch bootImageFilesByArch var bootImageFiles bootImageOutputs
if imageConfig != nil { if imageConfig != nil {
// Delegate the production of the boot image files to a module type specific method. // Delegate the production of the boot image files to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment) common := ctx.Module().(commonBootclasspathFragment)
bootImageFilesByArch = common.produceBootImageFiles(ctx, imageConfig) bootImageFiles = common.produceBootImageFiles(ctx, imageConfig)
if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
// Zip the boot image files up, if available. This will generate the zip file in a // Zip the boot image files up, if available. This will generate the zip file in a
// predefined location. // predefined location.
buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFilesByArch) buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch)
// Copy the dex jars of this fragment's content modules to their predefined locations. // Copy the dex jars of this fragment's content modules to their predefined locations.
copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule) copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule)
@ -620,7 +620,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// A prebuilt fragment cannot contribute to an apex. // A prebuilt fragment cannot contribute to an apex.
if !android.IsModulePrebuilt(ctx.Module()) { if !android.IsModulePrebuilt(ctx.Module()) {
// Provide the apex content info. // Provide the apex content info.
b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFilesByArch) b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles)
} }
} else { } else {
// Versioned fragments are not needed by make. // Versioned fragments are not needed by make.
@ -663,7 +663,7 @@ func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageCo
// provideApexContentInfo creates, initializes and stores the apex content info for use by other // provideApexContentInfo creates, initializes and stores the apex content info for use by other
// modules. // modules.
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFilesByArch bootImageFilesByArch) { func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) {
// Construct the apex content info from the config. // Construct the apex content info from the config.
info := BootclasspathFragmentApexContentInfo{ info := BootclasspathFragmentApexContentInfo{
// Populate the apex content info with paths to the dex jars. // Populate the apex content info with paths to the dex jars.
@ -674,14 +674,14 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
info.modules = imageConfig.modules info.modules = imageConfig.modules
global := dexpreopt.GetGlobalConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx)
if !global.DisableGenerateProfile { if !global.DisableGenerateProfile {
info.profilePathOnHost = imageConfig.profilePathOnHost info.profilePathOnHost = bootImageFiles.profile
info.profileInstallPathInApex = imageConfig.profileInstallPathInApex info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
} }
info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex() info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex()
} }
info.bootImageFilesByArch = bootImageFilesByArch info.bootImageFilesByArch = bootImageFiles.byArch
// Make the apex content info available for other modules. // Make the apex content info available for other modules.
ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info) ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
@ -934,9 +934,9 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
} }
// produceBootImageFiles builds the boot image files from the source if it is required. // produceBootImageFiles builds the boot image files from the source if it is required.
func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if SkipDexpreoptBootJars(ctx) { if SkipDexpreoptBootJars(ctx) {
return nil return bootImageOutputs{}
} }
// Only generate the boot image if the configuration does not skip it. // Only generate the boot image if the configuration does not skip it.
@ -948,21 +948,21 @@ func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleCo
// //
// If it could not create the files then it will return nil. Otherwise, it will return a map from // If it could not create the files then it will return nil. Otherwise, it will return a map from
// android.ArchType to the predefined paths of the boot image files. // android.ArchType to the predefined paths of the boot image files.
func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
global := dexpreopt.GetGlobalConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx)
if !shouldBuildBootImages(ctx.Config(), global) { if !shouldBuildBootImages(ctx.Config(), global) {
return nil return bootImageOutputs{}
} }
// Bootclasspath fragment modules that are for the platform do not produce a boot image. // Bootclasspath fragment modules that are for the platform do not produce a boot image.
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if apexInfo.IsForPlatform() { if apexInfo.IsForPlatform() {
return nil return bootImageOutputs{}
} }
// Bootclasspath fragment modules that are versioned do not produce a boot image. // Bootclasspath fragment modules that are versioned do not produce a boot image.
if android.IsModuleInVersionedSdk(ctx.Module()) { if android.IsModuleInVersionedSdk(ctx.Module()) {
return nil return bootImageOutputs{}
} }
// Build a profile for the image config and then use that to build the boot image. // Build a profile for the image config and then use that to build the boot image.
@ -972,11 +972,11 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
// Build boot image files for the android variants. // Build boot image files for the android variants.
androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
// Return the boot image files for the android variants for inclusion in an APEX and to be zipped // Return the boot image files for the android variants for inclusion in an APEX and to be zipped
// up for the dist. // up for the dist.
return androidBootImageFilesByArch return bootImageFiles
} }
func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries { func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries {
@ -1277,14 +1277,14 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
} }
// produceBootImageFiles extracts the boot image files from the APEX if available. // produceBootImageFiles extracts the boot image files from the APEX if available.
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch { func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) { if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
return nil return bootImageOutputs{}
} }
di := android.FindDeapexerProviderForModule(ctx) di := android.FindDeapexerProviderForModule(ctx)
if di == nil { if di == nil {
return nil // An error has been reported by FindDeapexerProviderForModule. return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule.
} }
profile := (android.WritablePath)(nil) profile := (android.WritablePath)(nil)
@ -1321,11 +1321,14 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
}) })
} }
} }
return files return bootImageOutputs{
files,
profile,
}
} else { } else {
if profile == nil { if profile == nil {
ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex") ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")
return nil return bootImageOutputs{}
} }
// Build boot image files for the android variants from the dex files provided by the contents // Build boot image files for the android variants from the dex files provided by the contents
// of this module. // of this module.

View file

@ -282,11 +282,6 @@ type bootImageConfig struct {
// Deprecated: Not initialized correctly, see struct comment. // Deprecated: Not initialized correctly, see struct comment.
profileLicenseMetadataFile android.OptionalPath profileLicenseMetadataFile android.OptionalPath
// Path to the image profile file on host (or empty, if profile is not generated).
//
// Deprecated: Not initialized correctly, see struct comment.
profilePathOnHost android.Path
// Target-dependent fields. // Target-dependent fields.
variants []*bootImageVariant variants []*bootImageVariant
@ -575,7 +570,7 @@ func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJars
// boot image files. // boot image files.
// //
// The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX. // The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX.
func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch { func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageOutputs {
return buildBootImageForOsType(ctx, image, profile, android.Android) return buildBootImageForOsType(ctx, image, profile, android.Android)
} }
@ -590,12 +585,22 @@ func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImag
buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS) buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS)
} }
// bootImageOutputs encapsulates information about boot images that were created/obtained by
// commonBootclasspathFragment.produceBootImageFiles.
type bootImageOutputs struct {
// Map from arch to the paths to the boot image files created/obtained for that arch.
byArch bootImageFilesByArch
// The path to the profile file created/obtained for the boot image.
profile android.WritablePath
}
// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType // buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType
// boot image files are required for and it creates rules to build the boot image // boot image files are required for and it creates rules to build the boot image
// files for all the required architectures for them. // files for all the required architectures for them.
// //
// It returns a map from android.ArchType to the predefined paths of the boot image files. // It returns a map from android.ArchType to the predefined paths of the boot image files.
func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch { func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageOutputs {
filesByArch := bootImageFilesByArch{} filesByArch := bootImageFilesByArch{}
for _, variant := range image.variants { for _, variant := range image.variants {
if variant.target.Os == requiredOsType { if variant.target.Os == requiredOsType {
@ -604,7 +609,10 @@ func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig,
} }
} }
return filesByArch return bootImageOutputs{
filesByArch,
profile,
}
} }
// buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files. // buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files.
@ -851,8 +859,6 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and
rule.Build("bootJarsProfile", "profile boot jars") rule.Build("bootJarsProfile", "profile boot jars")
image.profilePathOnHost = profile
return profile return profile
} }

View file

@ -436,10 +436,10 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.
profile := bootImageProfileRule(ctx, imageConfig) profile := bootImageProfileRule(ctx, imageConfig)
// Build boot image files for the android variants. // Build boot image files for the android variants.
androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile) androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
// Zip the android variant boot image files up. // Zip the android variant boot image files up.
buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFilesByArch) buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
// Build boot image files for the host variants. There are use directly by ART host side tests. // Build boot image files for the host variants. There are use directly by ART host side tests.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile) buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)