diff options
| author | Jiakai Zhang <jiakaiz@google.com> | 2021-09-09 08:09:41 +0000 |
|---|---|---|
| committer | Jiakai Zhang <jiakaiz@google.com> | 2021-09-15 09:01:07 +0000 |
| commit | ca9bc98e0cfe9a519cfdd13450a68f1ed7ad5b02 (patch) | |
| tree | ddf50ea990f4c9a1e00db3adde1b5dca22276be1 /dexpreopt | |
| parent | 709f02707d4c130f0b633de9d7134f9f34dbf569 (diff) | |
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
Diffstat (limited to 'dexpreopt')
| -rw-r--r-- | dexpreopt/dexpreopt.go | 54 | ||||
| -rw-r--r-- | dexpreopt/dexpreopt_test.go | 49 |
2 files changed, 78 insertions, 25 deletions
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index 1401c75d9..7733c1b43 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -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) diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go index 4ee61b6b0..798d77604 100644 --- a/dexpreopt/dexpreopt_test.go +++ b/dexpreopt/dexpreopt_test.go @@ -33,17 +33,35 @@ func testProductModuleConfig(ctx android.PathContext, name string) *ModuleConfig } func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig { + return createTestModuleConfig( + name, + fmt.Sprintf("/%s/app/test/%s.apk", partition, name), + android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name))) +} + +func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig { + return createTestModuleConfig( + name, + fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name), + android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name))) +} + +func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig { return &ModuleConfig{ Name: name, - DexLocation: fmt.Sprintf("/%s/app/test/%s.apk", partition, name), - BuildPath: android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)), - DexPath: android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)), + DexLocation: dexLocation, + BuildPath: buildPath, + DexPath: dexPath, UncompressedDex: false, HasApkLibraries: false, PreoptFlags: nil, ProfileClassListing: android.OptionalPath{}, ProfileIsTextListing: false, - EnforceUsesLibrariesStatusFile: android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)), + EnforceUsesLibrariesStatusFile: enforceUsesLibrariesStatusFile, EnforceUsesLibraries: false, ClassLoaderContexts: nil, Archs: []android.ArchType{android.Arm}, @@ -140,6 +158,29 @@ func TestDexPreoptSystemOther(t *testing.T) { } +func TestDexPreoptApexSystemServerJars(t *testing.T) { + config := android.TestConfig("out", nil, "", nil) + ctx := android.BuilderContextForTesting(config) + globalSoong := globalSoongConfigForTests() + global := GlobalConfigForTests(ctx) + module := testApexModuleConfig(ctx, "service-A", "com.android.apex1") + + global.ApexSystemServerJars = android.CreateTestConfiguredJarList( + []string{"com.android.apex1:service-A"}) + + rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module) + if err != nil { + t.Fatal(err) + } + + wantInstalls := android.RuleBuilderInstalls{ + {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"}, + {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"}, + } + + android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String()) +} + func TestDexPreoptProfile(t *testing.T) { config := android.TestConfig("out", nil, "", nil) ctx := android.BuilderContextForTesting(config) |
