Skip to content

Commit 8ad7f20

Browse files
author
Calin Juravle
committed
Use native ISA for dex code (in case there's a NativeBridge)
In the presence of a native bridge it is more efficient to compile the dex directly to the native ISA than to use the shared library ISA as a reference. This can be achieve by configuring the readonly system properties to map between the .so ISA and the desired dex code .ISA (e.g. ro.dalvik.vm.isa.ISA1=ISA2). Bug: 16185267 (cherry picked from commit I50baa7b37e1465b9adf72d6f6b96f526a08d59c7) (cherry picked from commit I8fe453a800812e382e8f41b5f7922997aa9c18a9) Change-Id: I6c9684149691285310c961189b58af8c7f47aff4
1 parent f328227 commit 8ad7f20

1 file changed

Lines changed: 54 additions & 31 deletions

File tree

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

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,9 @@ public PackageManagerService(Context context, Installer installer,
14021402

14031403
boolean didDexOptLibraryOrTool = false;
14041404

1405-
final List<String> instructionSets = getAllInstructionSets();
1405+
final List<String> allInstructionSets = getAllInstructionSets();
1406+
final String[] dexCodeInstructionSets =
1407+
getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
14061408

14071409
/**
14081410
* Ensure all external libraries have had dexopt run on them.
@@ -1412,7 +1414,7 @@ public PackageManagerService(Context context, Installer installer,
14121414
// (and framework jars) into all available architectures. It's possible
14131415
// to compile them only when we come across an app that uses them (there's
14141416
// already logic for that in scanPackageLI) but that adds some complexity.
1415-
for (String instructionSet : instructionSets) {
1417+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
14161418
for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
14171419
final String lib = libEntry.path;
14181420
if (lib == null) {
@@ -1421,16 +1423,16 @@ public PackageManagerService(Context context, Installer installer,
14211423

14221424
try {
14231425
byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
1424-
instructionSet,
1426+
dexCodeInstructionSet,
14251427
false);
14261428
if (dexoptRequired != DexFile.UP_TO_DATE) {
14271429
alreadyDexOpted.add(lib);
14281430

14291431
// The list of "shared libraries" we have at this point is
14301432
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1431-
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
1433+
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
14321434
} else {
1433-
mInstaller.patchoat(lib, Process.SYSTEM_UID, true, instructionSet);
1435+
mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
14341436
}
14351437
didDexOptLibraryOrTool = true;
14361438
}
@@ -1465,7 +1467,7 @@ public PackageManagerService(Context context, Installer installer,
14651467
// TODO: We could compile these only for the most preferred ABI. We should
14661468
// first double check that the dex files for these commands are not referenced
14671469
// by other system apps.
1468-
for (String instructionSet : instructionSets) {
1470+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
14691471
for (int i=0; i<frameworkFiles.length; i++) {
14701472
File libPath = new File(frameworkDir, frameworkFiles[i]);
14711473
String path = libPath.getPath();
@@ -1479,13 +1481,13 @@ public PackageManagerService(Context context, Installer installer,
14791481
}
14801482
try {
14811483
byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
1482-
instructionSet,
1484+
dexCodeInstructionSet,
14831485
false);
14841486
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
1485-
mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet);
1487+
mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
14861488
didDexOptLibraryOrTool = true;
14871489
} else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
1488-
mInstaller.patchoat(path, Process.SYSTEM_UID, true, instructionSet);
1490+
mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
14891491
didDexOptLibraryOrTool = true;
14901492
}
14911493
} catch (FileNotFoundException e) {
@@ -1509,8 +1511,8 @@ public PackageManagerService(Context context, Installer installer,
15091511
// small maintenance release update that the library and tool
15101512
// jars may be unchanged but APK could be removed resulting in
15111513
// unused dalvik-cache files.
1512-
for (String instructionSet : instructionSets) {
1513-
mInstaller.pruneDexCache(instructionSet);
1514+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1515+
mInstaller.pruneDexCache(dexCodeInstructionSet);
15141516
}
15151517

15161518
// Additionally, delete all dex files from the root directory
@@ -4632,9 +4634,10 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46324634
// 1.) we need to dexopt, either because we are forced or it is needed
46334635
// 2.) we are defering a needed dexopt
46344636
// 3.) we are skipping an unneeded dexopt
4637+
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
46354638
for (String path : paths) {
4636-
for (String instructionSet : instructionSets) {
4637-
if (!forceDex && pkg.mDexOptPerformed.contains(instructionSet)) {
4639+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
4640+
if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
46384641
continue;
46394642
}
46404643

@@ -4645,13 +4648,13 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46454648
// odex file and it matches the checksum of the image but not its base address,
46464649
// meaning we need to move it.
46474650
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
4648-
pkg.packageName, instructionSet, defer);
4651+
pkg.packageName, dexCodeInstructionSet, defer);
46494652
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
46504653
Log.i(TAG, "Running dexopt on: " + path + " pkg="
4651-
+ pkg.applicationInfo.packageName + " isa=" + instructionSet);
4654+
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet);
46524655
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
46534656
final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
4654-
pkg.packageName, instructionSet);
4657+
pkg.packageName, dexCodeInstructionSet);
46554658

46564659
if (ret < 0) {
46574660
// Don't bother running dexopt again if we failed, it will probably
@@ -4660,13 +4663,13 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46604663
return DEX_OPT_FAILED;
46614664
} else {
46624665
performedDexOpt = true;
4663-
pkg.mDexOptPerformed.add(instructionSet);
4666+
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
46644667
}
46654668
} else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
46664669
Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
46674670
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
46684671
final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
4669-
pkg.packageName, instructionSet);
4672+
pkg.packageName, dexCodeInstructionSet);
46704673

46714674
if (ret < 0) {
46724675
// Don't bother running patchoat again if we failed, it will probably
@@ -4675,7 +4678,7 @@ private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructio
46754678
return DEX_OPT_FAILED;
46764679
} else {
46774680
performedDexOpt = true;
4678-
pkg.mDexOptPerformed.add(instructionSet);
4681+
pkg.mDexOptPerformed.add(dexCodeInstructionSet);
46794682
}
46804683
}
46814684

@@ -4764,6 +4767,23 @@ private static List<String> getAllInstructionSets() {
47644767
return allInstructionSets;
47654768
}
47664769

4770+
/**
4771+
* Returns the instruction set that should be used to compile dex code. In the presence of
4772+
* a native bridge this might be different than the one shared libraries use.
4773+
*/
4774+
private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
4775+
String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
4776+
return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
4777+
}
4778+
4779+
private static String[] getDexCodeInstructionSets(String[] instructionSets) {
4780+
HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length);
4781+
for (String instructionSet : instructionSets) {
4782+
dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
4783+
}
4784+
return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
4785+
}
4786+
47674787
@Override
47684788
public void forceDexOpt(String packageName) {
47694789
enforceSystemOrRoot("forceDexOpt");
@@ -6183,7 +6203,8 @@ private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
61836203
ps.pkg.applicationInfo.primaryCpuAbi = null;
61846204
return;
61856205
} else {
6186-
mInstaller.rmdex(ps.codePathString, getPreferredInstructionSet());
6206+
mInstaller.rmdex(ps.codePathString,
6207+
getDexCodeInstructionSet(getPreferredInstructionSet()));
61876208
}
61886209
}
61896210
}
@@ -9412,10 +9433,10 @@ void cleanUpResourcesLI() {
94129433
if (instructionSets == null) {
94139434
throw new IllegalStateException("instructionSet == null");
94149435
}
9415-
9436+
String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
94169437
for (String codePath : allCodePaths) {
9417-
for (String instructionSet : instructionSets) {
9418-
int retCode = mInstaller.rmdex(codePath, instructionSet);
9438+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9439+
int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
94199440
if (retCode < 0) {
94209441
Slog.w(TAG, "Couldn't remove dex file for package: "
94219442
+ " at location " + codePath + ", retcode=" + retCode);
@@ -9695,8 +9716,9 @@ void cleanUpResourcesLI() {
96959716
if (instructionSets == null) {
96969717
throw new IllegalStateException("instructionSet == null");
96979718
}
9698-
for (String instructionSet : instructionSets) {
9699-
int retCode = mInstaller.rmdex(sourceFile, instructionSet);
9719+
String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
9720+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
9721+
int retCode = mInstaller.rmdex(sourceFile, dexCodeInstructionSet);
97009722
if (retCode < 0) {
97019723
Slog.w(TAG, "Couldn't remove dex file for package: "
97029724
+ " at location "
@@ -10199,9 +10221,10 @@ private int moveDexFilesLI(String oldCodePath, PackageParser.Package newPackage)
1019910221
// TODO: extend to move split APK dex files
1020010222
if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
1020110223
final String[] instructionSets = getAppDexInstructionSets(newPackage.applicationInfo);
10202-
for (String instructionSet : instructionSets) {
10224+
String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
10225+
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
1020310226
int retCode = mInstaller.movedex(oldCodePath, newPackage.baseCodePath,
10204-
instructionSet);
10227+
dexCodeInstructionSet);
1020510228
if (retCode != 0) {
1020610229
/*
1020710230
* Programs may be lazily run through dexopt, so the
@@ -10212,8 +10235,8 @@ private int moveDexFilesLI(String oldCodePath, PackageParser.Package newPackage)
1021210235
* file from a previous version of the package.
1021310236
*/
1021410237
newPackage.mDexOptPerformed.clear();
10215-
mInstaller.rmdex(oldCodePath, instructionSet);
10216-
mInstaller.rmdex(newPackage.baseCodePath, instructionSet);
10238+
mInstaller.rmdex(oldCodePath, dexCodeInstructionSet);
10239+
mInstaller.rmdex(newPackage.baseCodePath, dexCodeInstructionSet);
1021710240
}
1021810241
}
1021910242
}
@@ -11360,9 +11383,9 @@ private boolean getPackageSizeInfoLI(String packageName, int userHandle,
1136011383
// not just the first level.
1136111384
// TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
1136211385
// just the primary.
11386+
String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
1136311387
int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
11364-
publicSrcDir, asecPath, getAppDexInstructionSets(ps),
11365-
pStats);
11388+
publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
1136611389
if (res < 0) {
1136711390
return false;
1136811391
}

0 commit comments

Comments
 (0)