Skip to content

Commit 05e8f80

Browse files
committed
Reduce the frequency of calls to isDexOptNeededInternal.
The package manager maintains a set of dexopted instruction sets as a fast path to avoid calling expensive code. We were correctly adding elements to that list while performing dexopt, but were *not* adding elements to the list when isDexOptNeededInternal told us things were up to date. As a result, we'd hit the slow path 100% of the time on userdebug builds in the steady state, i.e, when the system did not dexopt anything since boot. With this change, we make sure isDexOptNeededInternal is called precisely once per boot in such case. This patch also fixes broken logic for apps that have multiple code paths. We must mark the paths as dexopted only if we've processed all paths. bug: 16828525 bug: 16868741 Change-Id: Icb59121fe915d892e677d9b7e9a4efd11555ae27
1 parent 6d9fe65 commit 05e8f80

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

services/core/java/com/android/server/pm/PackageManagerService.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4635,12 +4635,12 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46354635
// 2.) we are defering a needed dexopt
46364636
// 3.) we are skipping an unneeded dexopt
46374637
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
4638-
for (String path : paths) {
4639-
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4640-
if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4641-
continue;
4642-
}
4638+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4639+
if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
4640+
continue;
4641+
}
46434642

4643+
for (String path : paths) {
46444644
try {
46454645
// This will return DEXOPT_NEEDED if we either cannot find any odex file for this
46464646
// patckage or the one we find does not match the image checksum (i.e. it was
@@ -4661,10 +4661,9 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46614661
// just result in an error again. Also, don't bother dexopting for other
46624662
// paths & ISAs.
46634663
return DEX_OPT_FAILED;
4664-
} else {
4665-
performedDexOpt = true;
4666-
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
46674664
}
4665+
4666+
performedDexOpt = true;
46684667
} else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
46694668
Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
46704669
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
@@ -4676,10 +4675,9 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46764675
// just result in an error again. Also, don't bother dexopting for other
46774676
// paths & ISAs.
46784677
return DEX_OPT_FAILED;
4679-
} else {
4680-
performedDexOpt = true;
4681-
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
46824678
}
4679+
4680+
performedDexOpt = true;
46834681
}
46844682

46854683
// We're deciding to defer a needed dexopt. Don't bother dexopting for other
@@ -4706,6 +4704,13 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
47064704
return DEX_OPT_FAILED;
47074705
}
47084706
}
4707+
4708+
// At this point we haven't failed dexopt and we haven't deferred dexopt. We must
4709+
// either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
4710+
// it isn't required. We therefore mark that this package doesn't need dexopt unless
4711+
// it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
4712+
// it.
4713+
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
47094714
}
47104715

47114716
// If we've gotten here, we're sure that no error occurred and that we haven't

0 commit comments

Comments
 (0)