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) {
return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null);
public int dexopt(String apkPath, int uid, boolean isPublic,
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,
String instructionSet, boolean vmSafeMode, boolean debuggable, String outputPath) {
String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, String outputPath) {
StringBuilder builder = new StringBuilder("dexopt");
builder.append(' ');
builder.append(apkPath);
@@ -106,6 +109,8 @@ public class InstallerConnection {
builder.append(pkgName);
builder.append(' ');
builder.append(instructionSet);
builder.append(' ');
builder.append(dexoptNeeded);
builder.append(vmSafeMode ? " 1" : " 0");
builder.append(debuggable ? " 1" : " 0");
builder.append(' ');
@@ -113,25 +118,6 @@ public class InstallerConnection {
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() {
if (mSocket != null) {
return true;

View File

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

View File

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

View File

@@ -113,64 +113,48 @@ final class PackageDexOptimizer {
for (String path : paths) {
try {
// This will return DEXOPT_NEEDED if we either cannot find any odex file for this
// package or the one we find does not match the image checksum (i.e. it was
// compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
// odex file and it matches the checksum of the image but not its base address,
// meaning we need to move it.
final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
pkg.packageName, dexCodeInstructionSet, defer);
if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
Log.i(TAG, "Running dexopt on: " + path + " pkg="
final int dexoptNeeded;
if (forceDex) {
dexoptNeeded = DexFile.DEX2OAT_NEEDED;
} else {
dexoptNeeded = DexFile.getDexOptNeeded(path,
pkg.packageName, dexCodeInstructionSet, defer);
}
if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
// 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
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
+ " oatDir = " + oatDir);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
if (oatDir != null) {
int ret = mPackageManagerService.mInstaller.dexopt(
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);
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
dexoptNeeded, vmSafeMode, debuggable, oatDir);
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;
}
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) {
Slog.w(TAG, "Apk not found for dexopt: " + path);
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
// 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's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
// it.
@@ -209,10 +193,11 @@ final class PackageDexOptimizer {
* <li>Package location is not a directory, i.e. monolithic install.</li>
* </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
private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet)
throws IOException {
if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) {
return null;
@@ -222,7 +207,7 @@ final class PackageDexOptimizer {
File oatDir = getOatDir(codePath);
mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(),
dexInstructionSet);
return oatDir;
return oatDir.getAbsolutePath();
}
return null;
}

View File

@@ -1458,18 +1458,10 @@ public class PackageManagerService extends IPackageManager.Stub {
}
try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
dexCodeInstructionSet,
false);
if (dexoptRequired != DexFile.UP_TO_DATE) {
int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
alreadyDexOpted.add(lib);
// 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);
}
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
@@ -1515,13 +1507,9 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
try {
byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
dexCodeInstructionSet,
false);
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);
int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded);
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);