Preopt APEX system server jars.

The path to the artifacts will in the form of
/system/framework/oat/<arch>/<encoded-jar-path>@classes.{odex,vdex,art},
where <encoded-jar-path> is the path to the jar file with "/" replaced
by "@". For example,
/system/framework/oat/x86_64/apex@com.android.art@javalib@service-art.jar@classes.odex

There will be a follow-up CL to update ART runtime to recognize
artifacts in that path.

Test: m com.android.art
Bug: 194150908
Change-Id: Ic89fd63c4b1cd565684cead83fc91dae3bc97a4c
This commit is contained in:
Jiakai Zhang
2021-09-09 08:09:41 +00:00
parent 709f02707d
commit ca9bc98e0c
9 changed files with 518 additions and 54 deletions

View File

@@ -110,17 +110,12 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo
return true
}
// Don't preopt system server jars that are updatable.
if global.ApexSystemServerJars.ContainsJar(module.Name) {
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
// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
!global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk {
!AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk {
return true
}
@@ -201,6 +196,14 @@ func bootProfileCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig,
return profilePath
}
// Returns the dex location of a system server java library.
func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
}
return fmt.Sprintf("/system/framework/%s.jar", lib)
}
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -216,6 +219,13 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
}
toOdexPath := func(path string) string {
if global.ApexSystemServerJars.ContainsJar(module.Name) {
return filepath.Join(
"/system/framework/oat",
arch.String(),
strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
}
return filepath.Join(
filepath.Dir(path),
"oat",
@@ -234,20 +244,21 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
systemServerJars := NonApexSystemServerJars(ctx, global)
systemServerJars := AllSystemServerJars(ctx, global)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
if jarIndex := systemServerJars.IndexOfJar(module.Name); jarIndex >= 0 {
// System server jars should be dexpreopted together: class loader context of each jar
// should include all preceding jars on the system server classpath.
var clcHost android.Paths
var clcTarget []string
for _, lib := range systemServerJars[:jarIndex] {
for i := 0; i < jarIndex; i++ {
lib := systemServerJars.Jar(i)
clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
clcTarget = append(clcTarget, filepath.Join("/system/framework", lib+".jar"))
clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
}
// Copy the system server jar to a predefined location where dex2oat will find it.
@@ -362,7 +373,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
var compilerFilter string
if global.SystemServerJars.ContainsJar(module.Name) {
if systemServerJars.ContainsJar(module.Name) {
// Jars of system server, use the product option if it is set, speed otherwise.
if global.SystemServerCompilerFilter != "" {
compilerFilter = global.SystemServerCompilerFilter
@@ -416,7 +427,7 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g
// PRODUCT_SYSTEM_SERVER_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
// PRODUCT_OTHER_JAVA_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
if global.SystemServerJars.ContainsJar(module.Name) {
if systemServerJars.ContainsJar(module.Name) {
if global.AlwaysSystemServerDebugInfo {
debugInfo = true
} else if global.NeverSystemServerDebugInfo {
@@ -518,14 +529,15 @@ func makefileMatch(pattern, s string) bool {
}
}
var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars")
var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
// TODO: eliminate the superficial global config parameter by moving global config definition
// from java subpackage to dexpreopt.
func NonApexSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
return ctx.Config().Once(nonApexSystemServerJarsKey, func() interface{} {
return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.ApexSystemServerJars.CopyOfJars())
}).([]string)
func AllSystemServerJars(ctx android.PathContext, global *GlobalConfig) *android.ConfiguredJarList {
return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
allSystemServerJars := global.SystemServerJars.AppendList(global.ApexSystemServerJars)
return &allSystemServerJars
}).(*android.ConfiguredJarList)
}
// A predefined location for the system server dex jars. This is needed in order to generate
@@ -551,12 +563,12 @@ func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
mctx, isModule := ctx.(android.ModuleContext)
if isModule {
config := GetGlobalConfig(ctx)
jars := NonApexSystemServerJars(ctx, config)
jars := AllSystemServerJars(ctx, config)
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
depIndex := android.IndexList(dep.Name(), jars)
depIndex := jars.IndexOfJar(dep.Name())
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
jar := jars[jarIndex]
dep := jars[depIndex]
jar := jars.Jar(jarIndex)
dep := jars.Jar(depIndex)
mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
" '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
" references from '%s' to '%s'.\n", jar, dep, jar, dep)