@@ -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