Loading dexpreopt/dexpreopt.go +32 −49 Original line number Diff line number Diff line Loading @@ -41,21 +41,12 @@ import ( "android/soong/android" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" ) const SystemPartition = "/system/" const SystemOtherPartition = "/system_other/" type dependencyTag struct { blueprint.BaseDependencyTag name string } var SystemServerDepTag = dependencyTag{name: "system-server-dep"} var SystemServerForcedDepTag = dependencyTag{name: "system-server-forced-dep"} // GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a // ModuleConfig. The produced files and their install locations will be available through rule.Installs(). func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConfig, Loading Loading @@ -116,13 +107,6 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo } } // Don't preopt system server jars that are not Soong modules. if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) { if _, ok := ctx.(android.ModuleContext); !ok { return true } } // If OnlyPreoptBootImageAndSystemServer=true and module is not in boot class path skip // Also preopt system server jars since selinux prevents system server from loading anything from // /data. If we don't do this they will need to be extracted which is not favorable for RAM usage Loading Loading @@ -239,6 +223,8 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g invocationPath := odexPath.ReplaceExtension(ctx, "invocation") systemServerJars := NonUpdatableSystemServerJars(ctx, global) // The class loader context using paths in the build var classLoaderContextHost android.Paths Loading @@ -253,8 +239,8 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g var conditionalClassLoaderContextHost29 android.Paths var conditionalClassLoaderContextTarget29 []string var classLoaderContextHostString, classLoaderContextDeviceString string var classLoaderDeps android.Paths // A flag indicating if the '&' class loader context is used. unknownClassLoaderContext := false if module.EnforceUsesLibraries { usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...) Loading Loading @@ -298,49 +284,38 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g pathForLibrary(module, hidlBase)) conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29, filepath.Join("/system/framework", hidlBase+".jar")) classLoaderContextHostString = strings.Join(classLoaderContextHost.Strings(), ":") } else if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) { // We expect that all dexpreopted system server jars are Soong modules. mctx, isModule := ctx.(android.ModuleContext) if !isModule { panic("Cannot dexpreopt system server jar that is not a soong module.") } } else if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include preceding jars (which can be found as dependencies of the current jar // with a special tag). var jarsOnHost android.Paths var jarsOnDevice []string mctx.VisitDirectDepsWithTag(SystemServerDepTag, func(dep android.Module) { depName := mctx.OtherModuleName(dep) if jar, ok := dep.(interface{ DexJar() android.Path }); ok { jarsOnHost = append(jarsOnHost, jar.DexJar()) jarsOnDevice = append(jarsOnDevice, "/system/framework/"+depName+".jar") } else { mctx.ModuleErrorf("module \"%s\" is not a jar", depName) // should include all preceding jars on the system server classpath. for _, otherJar := range systemServerJars[:jarIndex] { classLoaderContextHost = append(classLoaderContextHost, SystemServerDexJarHostPath(ctx, otherJar)) classLoaderContextTarget = append(classLoaderContextTarget, "/system/framework/"+otherJar+".jar") } }) classLoaderContextHostString = strings.Join(jarsOnHost.Strings(), ":") classLoaderContextDeviceString = strings.Join(jarsOnDevice, ":") classLoaderDeps = jarsOnHost // Copy the system server jar to a predefined location where dex2oat will find it. dexPathHost := SystemServerDexJarHostPath(ctx, module.Name) rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String())) rule.Command().Text("cp -f").Input(module.DexPath).Output(dexPathHost) } else { // Pass special class loader context to skip the classpath and collision check. // This will get removed once LOCAL_USES_LIBRARIES is enforced. // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default // to the &. classLoaderContextHostString = `\&` unknownClassLoaderContext = true } rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String())) rule.Command().FlagWithOutput("rm -f ", odexPath) // Set values in the environment of the rule. These may be modified by construct_context.sh. if classLoaderContextHostString == `\&` { rule.Command().Text(`class_loader_context_arg=--class-loader-context=\&`) rule.Command().Text(`stored_class_loader_context_arg=""`) if unknownClassLoaderContext { rule.Command(). Text(`class_loader_context_arg=--class-loader-context=\&`). Text(`stored_class_loader_context_arg=""`) } else { rule.Command().Text("class_loader_context_arg=--class-loader-context=PCL[" + classLoaderContextHostString + "]") rule.Command().Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + classLoaderContextDeviceString + "]") rule.Command(). Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(classLoaderContextHost.Strings(), ":") + "]"). Implicits(classLoaderContextHost). Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(classLoaderContextTarget, ":") + "]") } if module.EnforceUsesLibraries { Loading Loading @@ -395,7 +370,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", module.PreoptBootClassPathDexFiles, ":"). Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":"). Flag("${class_loader_context_arg}"). Flag("${stored_class_loader_context_arg}").Implicits(classLoaderDeps). Flag("${stored_class_loader_context_arg}"). FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()). FlagWithInput("--dex-file=", module.DexPath). FlagWithArg("--dex-location=", dexLocationArg). Loading Loading @@ -609,6 +584,14 @@ func NonUpdatableSystemServerJars(ctx android.PathContext, global *GlobalConfig) }).([]string) } // A predefined location for the system server dex jars. This is needed in order to generate // class loader context for dex2oat, as the path to the jar in the Soong module may be unknown // at that time (Soong processes the jars in dependency order, which may be different from the // the system server classpath order). func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.OutputPath { return android.PathForOutput(ctx, ctx.Config().DeviceName(), "system_server_dexjars", jar+".jar") } func contains(l []string, s string) bool { for _, e := range l { if e == s { Loading java/dexpreopt_config.go +3 −10 Original line number Diff line number Diff line Loading @@ -30,9 +30,9 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string var dexpreoptJars = *DexpreoptedSystemServerJars(ctx.Config()) // 1) The jars that are dexpreopted. for _, m := range dexpreoptJars { nonUpdatable := dexpreopt.NonUpdatableSystemServerJars(ctx, global) // 1) Non-updatable jars. for _, m := range nonUpdatable { systemServerClasspathLocations = append(systemServerClasspathLocations, filepath.Join("/system/framework", m+".jar")) } Loading @@ -41,13 +41,6 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string { systemServerClasspathLocations = append(systemServerClasspathLocations, dexpreopt.GetJarLocationFromApexJarPair(m)) } // 3) The jars from make (which are not updatable, not preopted). for _, m := range dexpreopt.NonUpdatableSystemServerJars(ctx, global) { if !android.InList(m, dexpreoptJars) { systemServerClasspathLocations = append(systemServerClasspathLocations, filepath.Join("/system/framework", m+".jar")) } } if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) { panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d", len(systemServerClasspathLocations), Loading java/java.go +0 −47 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ import ( "path/filepath" "strconv" "strings" "sync" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/dexpreopt" "android/soong/java/config" "android/soong/tradefed" ) Loading Loading @@ -60,8 +58,6 @@ func init() { PropertyName: "java_tests", }, }) android.PostDepsMutators(RegisterPostDepsMutators) } func RegisterJavaBuildComponents(ctx android.RegistrationContext) { Loading Loading @@ -90,44 +86,6 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) { ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) } func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("ordered_system_server_jars", systemServerJarsDepsMutator) } var ( dexpreoptedSystemServerJarsKey = android.NewOnceKey("dexpreoptedSystemServerJars") dexpreoptedSystemServerJarsLock sync.Mutex ) func DexpreoptedSystemServerJars(config android.Config) *[]string { return config.Once(dexpreoptedSystemServerJarsKey, func() interface{} { return &[]string{} }).(*[]string) } // A PostDepsMutator pass that enforces total order on non-updatable system server jars. A total // order is neededed because such jars must be dexpreopted together (each jar on the list must have // all preceding jars in its class loader context). The total order must be compatible with the // partial order imposed by genuine dependencies between system server jars (which is not always // respected by the PRODUCT_SYSTEM_SERVER_JARS variable). // // An earlier mutator pass creates genuine dependencies, and this pass traverses the jars in that // order (which is partial and non-deterministic). This pass adds additional dependencies between // jars, making the order total and deterministic. It also constructs a global ordered list. func systemServerJarsDepsMutator(ctx android.BottomUpMutatorContext) { jars := dexpreopt.NonUpdatableSystemServerJars(ctx, dexpreopt.GetGlobalConfig(ctx)) name := ctx.ModuleName() if android.InList(name, jars) { dexpreoptedSystemServerJarsLock.Lock() defer dexpreoptedSystemServerJarsLock.Unlock() jars := DexpreoptedSystemServerJars(ctx.Config()) for _, dep := range *jars { ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerDepTag, dep) } *jars = append(*jars, name) } } func (j *Module) checkSdkVersion(ctx android.ModuleContext) { if j.SocSpecific() || j.DeviceSpecific() || (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { Loading Loading @@ -711,11 +669,6 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } else if j.shouldInstrumentStatic(ctx) { ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") } // services depend on com.android.location.provider, but dependency in not registered in a Blueprint file if ctx.ModuleName() == "services" { ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerForcedDepTag, "com.android.location.provider") } } func hasSrcExt(srcs []string, ext string) bool { Loading Loading
dexpreopt/dexpreopt.go +32 −49 Original line number Diff line number Diff line Loading @@ -41,21 +41,12 @@ import ( "android/soong/android" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" ) const SystemPartition = "/system/" const SystemOtherPartition = "/system_other/" type dependencyTag struct { blueprint.BaseDependencyTag name string } var SystemServerDepTag = dependencyTag{name: "system-server-dep"} var SystemServerForcedDepTag = dependencyTag{name: "system-server-forced-dep"} // GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a // ModuleConfig. The produced files and their install locations will be available through rule.Installs(). func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConfig, Loading Loading @@ -116,13 +107,6 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo } } // Don't preopt system server jars that are not Soong modules. if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) { if _, ok := ctx.(android.ModuleContext); !ok { return true } } // If OnlyPreoptBootImageAndSystemServer=true and module is not in boot class path skip // Also preopt system server jars since selinux prevents system server from loading anything from // /data. If we don't do this they will need to be extracted which is not favorable for RAM usage Loading Loading @@ -239,6 +223,8 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g invocationPath := odexPath.ReplaceExtension(ctx, "invocation") systemServerJars := NonUpdatableSystemServerJars(ctx, global) // The class loader context using paths in the build var classLoaderContextHost android.Paths Loading @@ -253,8 +239,8 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g var conditionalClassLoaderContextHost29 android.Paths var conditionalClassLoaderContextTarget29 []string var classLoaderContextHostString, classLoaderContextDeviceString string var classLoaderDeps android.Paths // A flag indicating if the '&' class loader context is used. unknownClassLoaderContext := false if module.EnforceUsesLibraries { usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...) Loading Loading @@ -298,49 +284,38 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g pathForLibrary(module, hidlBase)) conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29, filepath.Join("/system/framework", hidlBase+".jar")) classLoaderContextHostString = strings.Join(classLoaderContextHost.Strings(), ":") } else if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) { // We expect that all dexpreopted system server jars are Soong modules. mctx, isModule := ctx.(android.ModuleContext) if !isModule { panic("Cannot dexpreopt system server jar that is not a soong module.") } } else if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 { // System server jars should be dexpreopted together: class loader context of each jar // should include preceding jars (which can be found as dependencies of the current jar // with a special tag). var jarsOnHost android.Paths var jarsOnDevice []string mctx.VisitDirectDepsWithTag(SystemServerDepTag, func(dep android.Module) { depName := mctx.OtherModuleName(dep) if jar, ok := dep.(interface{ DexJar() android.Path }); ok { jarsOnHost = append(jarsOnHost, jar.DexJar()) jarsOnDevice = append(jarsOnDevice, "/system/framework/"+depName+".jar") } else { mctx.ModuleErrorf("module \"%s\" is not a jar", depName) // should include all preceding jars on the system server classpath. for _, otherJar := range systemServerJars[:jarIndex] { classLoaderContextHost = append(classLoaderContextHost, SystemServerDexJarHostPath(ctx, otherJar)) classLoaderContextTarget = append(classLoaderContextTarget, "/system/framework/"+otherJar+".jar") } }) classLoaderContextHostString = strings.Join(jarsOnHost.Strings(), ":") classLoaderContextDeviceString = strings.Join(jarsOnDevice, ":") classLoaderDeps = jarsOnHost // Copy the system server jar to a predefined location where dex2oat will find it. dexPathHost := SystemServerDexJarHostPath(ctx, module.Name) rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String())) rule.Command().Text("cp -f").Input(module.DexPath).Output(dexPathHost) } else { // Pass special class loader context to skip the classpath and collision check. // This will get removed once LOCAL_USES_LIBRARIES is enforced. // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default // to the &. classLoaderContextHostString = `\&` unknownClassLoaderContext = true } rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String())) rule.Command().FlagWithOutput("rm -f ", odexPath) // Set values in the environment of the rule. These may be modified by construct_context.sh. if classLoaderContextHostString == `\&` { rule.Command().Text(`class_loader_context_arg=--class-loader-context=\&`) rule.Command().Text(`stored_class_loader_context_arg=""`) if unknownClassLoaderContext { rule.Command(). Text(`class_loader_context_arg=--class-loader-context=\&`). Text(`stored_class_loader_context_arg=""`) } else { rule.Command().Text("class_loader_context_arg=--class-loader-context=PCL[" + classLoaderContextHostString + "]") rule.Command().Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + classLoaderContextDeviceString + "]") rule.Command(). Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(classLoaderContextHost.Strings(), ":") + "]"). Implicits(classLoaderContextHost). Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(classLoaderContextTarget, ":") + "]") } if module.EnforceUsesLibraries { Loading Loading @@ -395,7 +370,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", module.PreoptBootClassPathDexFiles, ":"). Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":"). Flag("${class_loader_context_arg}"). Flag("${stored_class_loader_context_arg}").Implicits(classLoaderDeps). Flag("${stored_class_loader_context_arg}"). FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()). FlagWithInput("--dex-file=", module.DexPath). FlagWithArg("--dex-location=", dexLocationArg). Loading Loading @@ -609,6 +584,14 @@ func NonUpdatableSystemServerJars(ctx android.PathContext, global *GlobalConfig) }).([]string) } // A predefined location for the system server dex jars. This is needed in order to generate // class loader context for dex2oat, as the path to the jar in the Soong module may be unknown // at that time (Soong processes the jars in dependency order, which may be different from the // the system server classpath order). func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.OutputPath { return android.PathForOutput(ctx, ctx.Config().DeviceName(), "system_server_dexjars", jar+".jar") } func contains(l []string, s string) bool { for _, e := range l { if e == s { Loading
java/dexpreopt_config.go +3 −10 Original line number Diff line number Diff line Loading @@ -30,9 +30,9 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string var dexpreoptJars = *DexpreoptedSystemServerJars(ctx.Config()) // 1) The jars that are dexpreopted. for _, m := range dexpreoptJars { nonUpdatable := dexpreopt.NonUpdatableSystemServerJars(ctx, global) // 1) Non-updatable jars. for _, m := range nonUpdatable { systemServerClasspathLocations = append(systemServerClasspathLocations, filepath.Join("/system/framework", m+".jar")) } Loading @@ -41,13 +41,6 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string { systemServerClasspathLocations = append(systemServerClasspathLocations, dexpreopt.GetJarLocationFromApexJarPair(m)) } // 3) The jars from make (which are not updatable, not preopted). for _, m := range dexpreopt.NonUpdatableSystemServerJars(ctx, global) { if !android.InList(m, dexpreoptJars) { systemServerClasspathLocations = append(systemServerClasspathLocations, filepath.Join("/system/framework", m+".jar")) } } if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) { panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d", len(systemServerClasspathLocations), Loading
java/java.go +0 −47 Original line number Diff line number Diff line Loading @@ -23,14 +23,12 @@ import ( "path/filepath" "strconv" "strings" "sync" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/dexpreopt" "android/soong/java/config" "android/soong/tradefed" ) Loading Loading @@ -60,8 +58,6 @@ func init() { PropertyName: "java_tests", }, }) android.PostDepsMutators(RegisterPostDepsMutators) } func RegisterJavaBuildComponents(ctx android.RegistrationContext) { Loading Loading @@ -90,44 +86,6 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) { ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) } func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("ordered_system_server_jars", systemServerJarsDepsMutator) } var ( dexpreoptedSystemServerJarsKey = android.NewOnceKey("dexpreoptedSystemServerJars") dexpreoptedSystemServerJarsLock sync.Mutex ) func DexpreoptedSystemServerJars(config android.Config) *[]string { return config.Once(dexpreoptedSystemServerJarsKey, func() interface{} { return &[]string{} }).(*[]string) } // A PostDepsMutator pass that enforces total order on non-updatable system server jars. A total // order is neededed because such jars must be dexpreopted together (each jar on the list must have // all preceding jars in its class loader context). The total order must be compatible with the // partial order imposed by genuine dependencies between system server jars (which is not always // respected by the PRODUCT_SYSTEM_SERVER_JARS variable). // // An earlier mutator pass creates genuine dependencies, and this pass traverses the jars in that // order (which is partial and non-deterministic). This pass adds additional dependencies between // jars, making the order total and deterministic. It also constructs a global ordered list. func systemServerJarsDepsMutator(ctx android.BottomUpMutatorContext) { jars := dexpreopt.NonUpdatableSystemServerJars(ctx, dexpreopt.GetGlobalConfig(ctx)) name := ctx.ModuleName() if android.InList(name, jars) { dexpreoptedSystemServerJarsLock.Lock() defer dexpreoptedSystemServerJarsLock.Unlock() jars := DexpreoptedSystemServerJars(ctx.Config()) for _, dep := range *jars { ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerDepTag, dep) } *jars = append(*jars, name) } } func (j *Module) checkSdkVersion(ctx android.ModuleContext) { if j.SocSpecific() || j.DeviceSpecific() || (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { Loading Loading @@ -711,11 +669,6 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } else if j.shouldInstrumentStatic(ctx) { ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") } // services depend on com.android.location.provider, but dependency in not registered in a Blueprint file if ctx.ModuleName() == "services" { ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerForcedDepTag, "com.android.location.provider") } } func hasSrcExt(srcs []string, ext string) bool { Loading