Move the Once cache for dexpreopt.GlobalConfig into the dexpreopt package. am: dae8a80426 am: 0064a8888e

Change-Id: Ic9a3af4b8d004d36b791a76b61060be111e33ac6
This commit is contained in:
Automerger Merge Worker
2020-01-25 03:22:18 +00:00
7 changed files with 88 additions and 77 deletions

View File

@@ -176,10 +176,9 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl
return constructPath(ctx, path).(android.WritablePath)
}
// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig
// struct. LoadGlobalConfig is used directly in Soong and in dexpreopt_gen
// called from Make to read the $OUT/dexpreopt.config written by Make.
func LoadGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error) {
// ParseGlobalConfig parses the given data assumed to be read from the global
// dexpreopt.config file into a GlobalConfig struct.
func ParseGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error) {
type GlobalJSONConfig struct {
GlobalConfig
@@ -202,10 +201,65 @@ func LoadGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error
return config.GlobalConfig, nil
}
// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct. It is not used in Soong, which
// receives a ModuleConfig struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called from oMake to
// read the module dexpreopt.config written by Make.
func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
type globalConfigAndRaw struct {
global GlobalConfig
data []byte
}
// GetGlobalConfig returns the global dexpreopt.config that's created in the
// make config phase. It is loaded once the first time it is called for any
// ctx.Config(), and returns the same data for all future calls with the same
// ctx.Config(). A value can be inserted for tests using
// setDexpreoptTestGlobalConfig.
func GetGlobalConfig(ctx android.PathContext) GlobalConfig {
return getGlobalConfigRaw(ctx).global
}
// GetGlobalConfigRawData is the same as GetGlobalConfig, except that it returns
// the literal content of dexpreopt.config.
func GetGlobalConfigRawData(ctx android.PathContext) []byte {
return getGlobalConfigRaw(ctx).data
}
var globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig")
var testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(globalConfigOnceKey, func() interface{} {
if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
panic(err)
} else if data != nil {
globalConfig, err := ParseGlobalConfig(ctx, data)
if err != nil {
panic(err)
}
return globalConfigAndRaw{globalConfig, data}
}
// No global config filename set, see if there is a test config set
return ctx.Config().Once(testGlobalConfigOnceKey, func() interface{} {
// Nope, return a config with preopting disabled
return globalConfigAndRaw{GlobalConfig{
DisablePreopt: true,
DisableGenerateProfile: true,
}, nil}
})
}).(globalConfigAndRaw)
}
// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig
// will return. It must be called before the first call to GetGlobalConfig for
// the config.
func SetTestGlobalConfig(config android.Config, globalConfig GlobalConfig) {
config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}
// ParseModuleConfig parses a per-module dexpreopt.config file into a
// ModuleConfig struct. It is not used in Soong, which receives a ModuleConfig
// struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called
// from Make to read the module dexpreopt.config written in the Make config
// stage.
func ParseModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
type ModuleJSONConfig struct {
ModuleConfig
@@ -304,9 +358,10 @@ type globalJsonSoongConfig struct {
ConstructContext string
}
// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
// ParseGlobalSoongConfig parses the given data assumed to be read from the
// global dexpreopt_soong.config file into a GlobalSoongConfig struct. It is
// only used in dexpreopt_gen.
func ParseGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
var jc globalJsonSoongConfig
err := json.Unmarshal(data, &jc)

View File

@@ -84,9 +84,9 @@ func main() {
os.Exit(2)
}
globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData)
globalSoongConfig, err := dexpreopt.ParseGlobalSoongConfig(ctx, globalSoongConfigData)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading global Soong config %q: %s\n", *globalSoongConfigPath, err)
fmt.Fprintf(os.Stderr, "error parsing global Soong config %q: %s\n", *globalSoongConfigPath, err)
os.Exit(2)
}
@@ -96,9 +96,9 @@ func main() {
os.Exit(2)
}
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData)
globalConfig, err := dexpreopt.ParseGlobalConfig(ctx, globalConfigData)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
fmt.Fprintf(os.Stderr, "error parsing global config %q: %s\n", *globalConfigPath, err)
os.Exit(2)
}
@@ -108,9 +108,9 @@ func main() {
os.Exit(2)
}
moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData)
moduleConfig, err := dexpreopt.ParseModuleConfig(ctx, moduleConfigData)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err)
fmt.Fprintf(os.Stderr, "error parsing module config %q: %s\n", *moduleConfigPath, err)
os.Exit(2)
}

View File

@@ -59,7 +59,7 @@ type DexpreoptProperties struct {
}
func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisablePreopt {
return true
@@ -96,7 +96,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
}
func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx))
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
@@ -105,7 +105,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
}
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
bootImage := defaultBootImageConfig(ctx)
if global.UseApexImage {
bootImage = frameworkJZBootImageConfig(ctx)

View File

@@ -162,7 +162,7 @@ func dexpreoptBootJarsFactory() android.Singleton {
}
func skipDexpreoptBootJars(ctx android.PathContext) bool {
if dexpreoptGlobalConfig(ctx).DisablePreopt {
if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
return true
}
@@ -195,7 +195,7 @@ func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]and
files := artBootImageConfig(ctx).imagesDeps
// For JIT-zygote config, also include dexpreopt files for the primary JIT-zygote image.
if dexpreoptGlobalConfig(ctx).UseApexImage {
if dexpreopt.GetGlobalConfig(ctx).UseApexImage {
for arch, paths := range artJZBootImageConfig(ctx).imagesDeps {
files[arch] = append(files[arch], paths...)
}
@@ -213,7 +213,7 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config")
writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
// and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds.
@@ -305,7 +305,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
arch android.ArchType, profile android.Path, missingDeps []string) android.WritablePaths {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
@@ -444,7 +444,7 @@ Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see
func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
return nil
@@ -499,7 +499,7 @@ var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
return nil
@@ -587,7 +587,7 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
}
func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) {
data := dexpreoptGlobalConfigRaw(ctx).data
data := dexpreopt.GetGlobalConfigRawData(ctx)
ctx.Build(pctx, android.BuildParams{
Rule: android.WriteFile,

View File

@@ -49,7 +49,7 @@ func TestDexpreoptBootJars(t *testing.T) {
pathCtx := android.PathContextForTesting(config)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext()

View File

@@ -22,56 +22,12 @@ import (
"android/soong/dexpreopt"
)
// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any
// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted
// for tests using setDexpreoptTestGlobalConfig.
func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
return dexpreoptGlobalConfigRaw(ctx).global
}
type globalConfigAndRaw struct {
global dexpreopt.GlobalConfig
data []byte
}
func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
panic(err)
} else if data != nil {
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data)
if err != nil {
panic(err)
}
return globalConfigAndRaw{globalConfig, data}
}
// No global config filename set, see if there is a test config set
return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
// Nope, return a config with preopting disabled
return globalConfigAndRaw{dexpreopt.GlobalConfig{
DisablePreopt: true,
DisableGenerateProfile: true,
}, nil}
})
}).(globalConfigAndRaw)
}
// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must
// be called before the first call to dexpreoptGlobalConfig for the config.
func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
// ctx.Config().
func systemServerClasspath(ctx android.PathContext) []string {
return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
var systemServerClasspathLocations []string
for _, m := range global.SystemServerJars {
@@ -132,7 +88,7 @@ var (
func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
return ctx.Config().Once(bootImageConfigKey, func() interface{} {
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
targets := dexpreoptTargets(ctx)
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
@@ -273,7 +229,7 @@ func frameworkJZBootImageConfig(ctx android.PathContext) bootImageConfig {
func defaultBootclasspath(ctx android.PathContext) []string {
return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
global := dexpreoptGlobalConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
image := defaultBootImageConfig(ctx)
updatableBootclasspath := make([]string, len(global.UpdatableBootJars))

View File

@@ -99,7 +99,7 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) {
t.Helper()
pathCtx := android.PathContextForTesting(config)
setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -118,7 +118,7 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config
ctx := testContext()
pathCtx := android.PathContextForTesting(config)
setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles("Android.bp")