am f324d245: Merge "Reuse dexopt method for both dex2oat and patchoat."

* commit 'f324d245fdd07ac14ab312d1a5fa04a4e8dfcceb':
  Reuse dexopt method for both dex2oat and patchoat.
This commit is contained in:
Richard Uhler
2015-04-09 14:31:10 +00:00
committed by Android Git Automerger
5 changed files with 64 additions and 124 deletions

View File

@@ -90,12 +90,15 @@ public class InstallerConnection {
} }
} }
public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) { public int dexopt(String apkPath, int uid, boolean isPublic,
return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null); String instructionSet, int dexoptNeeded) {
return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded,
false, false, null);
} }
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, boolean vmSafeMode, boolean debuggable, String outputPath) { String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, String outputPath) {
StringBuilder builder = new StringBuilder("dexopt"); StringBuilder builder = new StringBuilder("dexopt");
builder.append(' '); builder.append(' ');
builder.append(apkPath); builder.append(apkPath);
@@ -106,6 +109,8 @@ public class InstallerConnection {
builder.append(pkgName); builder.append(pkgName);
builder.append(' '); builder.append(' ');
builder.append(instructionSet); builder.append(instructionSet);
builder.append(' ');
builder.append(dexoptNeeded);
builder.append(vmSafeMode ? " 1" : " 0"); builder.append(vmSafeMode ? " 1" : " 0");
builder.append(debuggable ? " 1" : " 0"); builder.append(debuggable ? " 1" : " 0");
builder.append(' '); builder.append(' ');
@@ -113,25 +118,6 @@ public class InstallerConnection {
return execute(builder.toString()); return execute(builder.toString());
} }
public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
return patchoat(apkPath, uid, isPublic, "*", instructionSet);
}
public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet) {
StringBuilder builder = new StringBuilder("patchoat");
builder.append(' ');
builder.append(apkPath);
builder.append(' ');
builder.append(uid);
builder.append(isPublic ? " 1" : " 0");
builder.append(' ');
builder.append(pkgName);
builder.append(' ');
builder.append(instructionSet);
return execute(builder.toString());
}
private boolean connect() { private boolean connect() {
if (mSocket != null) { if (mSocket != null) {
return true; return true;

View File

@@ -465,12 +465,11 @@ public class ZygoteInit {
try { try {
for (String classPathElement : classPathElements) { for (String classPathElement : classPathElements) {
final byte dexopt = DexFile.isDexOptNeededInternal(classPathElement, "*", instructionSet, final int dexoptNeeded = DexFile.getDexOptNeeded(
false /* defer */); classPathElement, "*", instructionSet, false /* defer */);
if (dexopt == DexFile.DEXOPT_NEEDED) { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
installer.dexopt(classPathElement, Process.SYSTEM_UID, false, instructionSet); installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
} else if (dexopt == DexFile.PATCHOAT_NEEDED) { instructionSet, dexoptNeeded);
installer.patchoat(classPathElement, Process.SYSTEM_UID, false, instructionSet);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {

View File

@@ -55,43 +55,25 @@ public final class Installer extends SystemService {
return mInstaller.execute(builder.toString()); return mInstaller.execute(builder.toString());
} }
public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName, public int dexopt(String apkPath, int uid, boolean isPublic,
String instructionSet) { String instructionSet, int dexoptNeeded) {
if (!isValidInstructionSet(instructionSet)) { if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet); Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1; return -1;
} }
return mInstaller.patchoat(apkPath, uid, isPublic, pkgName, instructionSet); return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded);
}
public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1;
}
return mInstaller.patchoat(apkPath, uid, isPublic, instructionSet);
}
public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1;
}
return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet);
} }
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, boolean vmSafeMode, boolean debuggable, String instructionSet, int dexoptNeeded, boolean vmSafeMode,
@Nullable String outputPath) { boolean debuggable, @Nullable String outputPath) {
if (!isValidInstructionSet(instructionSet)) { if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet); Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1; return -1;
} }
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName,
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode, instructionSet, dexoptNeeded, vmSafeMode,
debuggable, outputPath); debuggable, outputPath);
} }

View File

@@ -113,64 +113,48 @@ final class PackageDexOptimizer {
for (String path : paths) { for (String path : paths) {
try { try {
// This will return DEXOPT_NEEDED if we either cannot find any odex file for this final int dexoptNeeded;
// package or the one we find does not match the image checksum (i.e. it was if (forceDex) {
// compiled against an old image). It will return PATCHOAT_NEEDED if we can find a dexoptNeeded = DexFile.DEX2OAT_NEEDED;
// odex file and it matches the checksum of the image but not its base address, } else {
// meaning we need to move it. dexoptNeeded = DexFile.getDexOptNeeded(path,
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path, pkg.packageName, dexCodeInstructionSet, defer);
pkg.packageName, dexCodeInstructionSet, defer); }
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet); if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
Log.i(TAG, "Running dexopt on: " + path + " pkg=" // We're deciding to defer a needed dexopt. Don't bother dexopting for other
// paths and instruction sets. We'll deal with them all together when we process
// our list of deferred dexopts.
addPackageForDeferredDexopt(pkg);
return DEX_OPT_DEFERRED;
}
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
final String dexoptType;
String oatDir = null;
if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
dexoptType = "dex2oat";
oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
} else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
dexoptType = "patchoat";
} else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
dexoptType = "self patchoat";
} else {
throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
}
Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
+ " oatDir = " + oatDir); + " oatDir = " + oatDir);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
if (oatDir != null) { !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
int ret = mPackageManagerService.mInstaller.dexopt( dexoptNeeded, vmSafeMode, debuggable, oatDir);
path, sharedGid, !pkg.isForwardLocked(), pkg.packageName,
dexCodeInstructionSet, vmSafeMode, debuggable,
oatDir.getAbsolutePath());
if (ret < 0) {
return DEX_OPT_FAILED;
}
} else {
final int ret = mPackageManagerService.mInstaller
.dexopt(path, sharedGid,
!pkg.isForwardLocked(), pkg.packageName,
dexCodeInstructionSet,
vmSafeMode, debuggable, null);
if (ret < 0) {
return DEX_OPT_FAILED;
}
}
performedDexOpt = true;
} else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mPackageManagerService.mInstaller.patchoat(path, sharedGid,
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet);
if (ret < 0) { if (ret < 0) {
// Don't bother running patchoat again if we failed, it will probably
// just result in an error again. Also, don't bother dexopting for other
// paths & ISAs.
return DEX_OPT_FAILED; return DEX_OPT_FAILED;
} }
performedDexOpt = true; performedDexOpt = true;
} }
// We're deciding to defer a needed dexopt. Don't bother dexopting for other
// paths and instruction sets. We'll deal with them all together when we process
// our list of deferred dexopts.
if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
addPackageForDeferredDexopt(pkg);
return DEX_OPT_DEFERRED;
}
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Slog.w(TAG, "Apk not found for dexopt: " + path); Slog.w(TAG, "Apk not found for dexopt: " + path);
return DEX_OPT_FAILED; return DEX_OPT_FAILED;
@@ -187,7 +171,7 @@ final class PackageDexOptimizer {
} }
// At this point we haven't failed dexopt and we haven't deferred dexopt. We must // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
// either have either succeeded dexopt, or have had isDexOptNeededInternal tell us // either have either succeeded dexopt, or have had getDexOptNeeded tell us
// it isn't required. We therefore mark that this package doesn't need dexopt unless // it isn't required. We therefore mark that this package doesn't need dexopt unless
// it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
// it. // it.
@@ -209,10 +193,11 @@ final class PackageDexOptimizer {
* <li>Package location is not a directory, i.e. monolithic install.</li> * <li>Package location is not a directory, i.e. monolithic install.</li>
* </ul> * </ul>
* *
* @return oat directory or null, if oat directory cannot be created. * @return Absolute path to the oat directory or null, if oat directory
* cannot be created.
*/ */
@Nullable @Nullable
private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
throws IOException { throws IOException {
if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) { if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
return null; return null;
@@ -222,7 +207,7 @@ final class PackageDexOptimizer {
File oatDir = getOatDir(codePath); File oatDir = getOatDir(codePath);
mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(), mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
dexInstructionSet); dexInstructionSet);
return oatDir; return oatDir.getAbsolutePath();
} }
return null; return null;
} }

View File

@@ -1458,18 +1458,10 @@ public class PackageManagerService extends IPackageManager.Stub {
} }
try { try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
dexCodeInstructionSet, if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
false);
if (dexoptRequired != DexFile.UP_TO_DATE) {
alreadyDexOpted.add(lib); alreadyDexOpted.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
// The list of "shared libraries" we have at this point is
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
} else {
mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
}
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib); Slog.w(TAG, "Library not found: " + lib);
@@ -1515,13 +1507,9 @@ public class PackageManagerService extends IPackageManager.Stub {
continue; continue;
} }
try { try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
dexCodeInstructionSet, if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
false); mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
} else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path); Slog.w(TAG, "Jar not found: " + path);