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
// 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)
@ -583,16 +583,16 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// Perform hidden API processing.
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
var bootImageFilesByArch bootImageFilesByArch
var bootImageFiles bootImageOutputs
if imageConfig != nil {
// Delegate the production of the boot image files to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
bootImageFilesByArch = common.produceBootImageFiles(ctx, imageConfig)
bootImageFiles = common.produceBootImageFiles(ctx, imageConfig)
if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
// Zip the boot image files up, if available. This will generate the zip file in a
// 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.
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.
if !android.IsModulePrebuilt(ctx.Module()) {
// Provide the apex content info.
b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFilesByArch)
b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles)
}
} else {
// 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
// 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.
info := BootclasspathFragmentApexContentInfo{
// 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
global := dexpreopt.GetGlobalConfig(ctx)
if !global.DisableGenerateProfile {
info.profilePathOnHost = imageConfig.profilePathOnHost
info.profilePathOnHost = bootImageFiles.profile
info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
}
info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex()
}
info.bootImageFilesByArch = bootImageFilesByArch
info.bootImageFilesByArch = bootImageFiles.byArch
// Make the apex content info available for other modules.
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.
func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if SkipDexpreoptBootJars(ctx) {
return nil
return bootImageOutputs{}
}
// 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
// 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)
if !shouldBuildBootImages(ctx.Config(), global) {
return nil
return bootImageOutputs{}
}
// Bootclasspath fragment modules that are for the platform do not produce a boot image.
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if apexInfo.IsForPlatform() {
return nil
return bootImageOutputs{}
}
// Bootclasspath fragment modules that are versioned do not produce a boot image.
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.
@ -972,11 +972,11 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
// 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
// up for the dist.
return androidBootImageFilesByArch
return bootImageFiles
}
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.
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
return nil
return bootImageOutputs{}
}
di := android.FindDeapexerProviderForModule(ctx)
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)
@ -1321,11 +1321,14 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
})
}
}
return files
return bootImageOutputs{
files,
profile,
}
} else {
if profile == nil {
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
// of this module.

View file

@ -282,11 +282,6 @@ type bootImageConfig struct {
// Deprecated: Not initialized correctly, see struct comment.
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.
variants []*bootImageVariant
@ -575,7 +570,7 @@ func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJars
// boot image files.
//
// 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)
}
@ -590,12 +585,22 @@ func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImag
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
// boot image files are required for and it creates rules to build the boot image
// files for all the required architectures for them.
//
// 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{}
for _, variant := range image.variants {
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.
@ -851,8 +859,6 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and
rule.Build("bootJarsProfile", "profile boot jars")
image.profilePathOnHost = profile
return profile
}

View file

@ -436,10 +436,10 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.
profile := bootImageProfileRule(ctx, imageConfig)
// 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.
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.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)