Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84867864 authored by David Brazdil's avatar David Brazdil Committed by Android (Google) Code Review
Browse files

Merge "Add 'package compile' shell command"

parents f5c02746 493411ac
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -452,6 +452,9 @@ interface IPackageManager {
     */
    boolean performDexOptIfNeeded(String packageName, String instructionSet);

    boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
            boolean extractOnly, boolean force);

    void forceDexOpt(String packageName);

    /**
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ public class BackgroundDexOptService extends JobService {
                        continue;
                    }
                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles,
                            /* extractOnly */ false)) {
                            /* extractOnly */ false, /* force */ false)) {
                        // there was a problem running dexopt,
                        // remember this so we do not keep retrying.
                        sFailedPackageNames.add(pkg);
+24 −20
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ final class PackageDexOptimizer {
     * {@link PackageManagerService#mInstallLock}.
     */
    int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
            boolean inclDependencies, boolean useProfiles, boolean extractOnly) {
            boolean inclDependencies, boolean useProfiles, boolean extractOnly, boolean force) {
        ArraySet<String> done;
        if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
            done = new ArraySet<String>();
@@ -97,7 +97,7 @@ final class PackageDexOptimizer {
            }
            try {
                return performDexOptLI(pkg, instructionSets, done, useProfiles,
                        extractOnly);
                        extractOnly, force);
            } finally {
                if (useLock) {
                    mDexoptWakeLock.release();
@@ -107,7 +107,7 @@ final class PackageDexOptimizer {
    }

    private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
            ArraySet<String> done, boolean useProfiles, boolean extractOnly) {
            ArraySet<String> done, boolean useProfiles, boolean extractOnly, boolean force) {
        final String[] instructionSets = targetInstructionSets != null ?
                targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);

@@ -128,17 +128,26 @@ final class PackageDexOptimizer {
        final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
        final boolean debuggable = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

        if (useProfiles) {
            // If we do a profile guided compilation then we might recompile
            // the same package if more profile information is available.
            force = true;
        }

        final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
        boolean performedDexOpt = false;
        final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
        for (String dexCodeInstructionSet : dexCodeInstructionSets) {
            if (!useProfiles && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
                // Skip only if we do not use profiles since they might trigger a recompilation.
            if (!force && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
                continue;
            }

            for (String path : paths) {
                int dexoptNeeded;

                if (force) {
                    dexoptNeeded = DexFile.DEX2OAT_NEEDED;
                } else {
                    try {
                        dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
                                dexCodeInstructionSet, /* defer */false);
@@ -146,17 +155,12 @@ final class PackageDexOptimizer {
                        Slog.w(TAG, "IOException reading apk: " + path, ioe);
                        return DEX_OPT_FAILED;
                    }
                }

                if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
                    if (useProfiles) {
                        // If we do a profile guided compilation then we might recompile the same
                        // package if more profile information is available.
                        dexoptNeeded = DexFile.DEX2OAT_NEEDED;
                    } else {
                    // No dexopt needed and we don't use profiles. Nothing to do.
                    continue;
                }
                }
                final String dexoptType;
                String oatDir = null;
                if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) {
@@ -252,7 +256,7 @@ final class PackageDexOptimizer {
                // TODO: Analyze and investigate if we (should) profile libraries.
                // Currently this will do a full compilation of the library.
                performDexOptLI(libPkg, instructionSets, done, /*useProfiles*/ false,
                        /* extractOnly */ false);
                        /* extractOnly */ false, /* force */ false);
            }
        }
    }
+13 −11
Original line number Diff line number Diff line
@@ -6639,7 +6639,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (pkgs != null) {
                for (String pkg : pkgs) {
                    performDexOpt(pkg, null /* instructionSet */, false /* useProfiles */,
                            true /* extractOnly */);
                            true /* extractOnly */, false /* force */);
                }
            }
        }
@@ -6676,26 +6676,28 @@ public class PackageManagerService extends IPackageManager.Stub {
    @Override
    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
        return performDexOptTraced(packageName, instructionSet, false /* useProfiles */,
                false /* extractOnly */);
                false /* extractOnly */, false /* force */);
    }
    @Override
    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
            boolean extractOnly) {
        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly);
            boolean extractOnly, boolean force) {
        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly, force);
    }
    private boolean performDexOptTraced(String packageName, String instructionSet,
                boolean useProfiles, boolean extractOnly) {
                boolean useProfiles, boolean extractOnly, boolean force) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
        try {
            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly);
            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly,
                    force);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }
    private boolean performDexOptInternal(String packageName, String instructionSet,
                boolean useProfiles, boolean extractOnly) {
                boolean useProfiles, boolean extractOnly, boolean force) {
        PackageParser.Package p;
        final String targetInstructionSet;
        synchronized (mPackages) {
@@ -6707,7 +6709,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            targetInstructionSet = instructionSet != null ? instructionSet :
                    getPrimaryInstructionSet(p.applicationInfo);
            if (!useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
            if (!force && !useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
                // Skip only if we do not use profiles since they might trigger a recompilation.
                return false;
            }
@@ -6717,7 +6719,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            synchronized (mInstallLock) {
                final String[] instructionSets = new String[] { targetInstructionSet };
                int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
                        true /* inclDependencies */, useProfiles, extractOnly);
                        true /* inclDependencies */, useProfiles, extractOnly, force);
                return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
            }
        } finally {
@@ -6763,7 +6765,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            // Don't use profiles since that may cause compilation to be skipped.
            final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
                    true /* inclDependencies */, false /* useProfiles */,
                    false /* extractOnly */);
                    false /* extractOnly */, true /* force */);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -13031,7 +13033,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                // method because `pkg` is not in `mPackages` yet.
                int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
                        false /* inclDependencies */, false /* useProfiles */,
                        true /* extractOnly */);
                        true /* extractOnly */, false /* force */);
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
                    String msg = "Extracking package failed for " + pkgName;
+70 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.PrintWriterPrinter;
@@ -96,6 +97,8 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runInstallCreate();
                case "install-write":
                    return runInstallWrite();
                case "compile":
                    return runCompile();
                case "list":
                    return runList();
                case "uninstall":
@@ -227,6 +230,67 @@ class PackageManagerShellCommand extends ShellCommand {
        return doWriteSession(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
    }

    private int runCompile() throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
        boolean useJitProfiles = false;
        boolean extractOnly = false;
        boolean forceCompilation = false;
        String compilationMode = "default";

        String opt;
        while ((opt = getNextOption()) != null) {
            switch (opt) {
                case "-m":
                    compilationMode = getNextArgRequired();
                    break;
                case "-f":
                    forceCompilation = true;
                    break;
                default:
                    pw.println("Error: Unknown option: " + opt);
                    return 1;
            }
        }

        switch (compilationMode) {
            case "default":
                useJitProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
                extractOnly = false;
                break;
            case "all":
                useJitProfiles = false;
                extractOnly = false;
                break;
            case "profile":
                useJitProfiles = true;
                extractOnly = false;
                break;
            case "extract":
                useJitProfiles = false;
                extractOnly = true;
                break;
            default:
                pw.println("Error: Unknown compilation mode: " + compilationMode);
                return 1;
        }

        String packageName = getNextArg();
        if (packageName == null) {
            pw.println("Error: package name not specified");
            return 1;
        }

        boolean success = mInterface.performDexOpt(packageName, null /* instructionSet */,
                useJitProfiles, extractOnly, forceCompilation);
        if (success) {
            pw.println("Success");
            return 0;
        } else {
            pw.println("Failure: package " + packageName + " could not be compiled");
            return 1;
        }
    }

    private int runList() throws RemoteException {
        final PrintWriter pw = getOutPrintWriter();
        final String type = getNextArg();
@@ -1069,6 +1133,12 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("  help");
        pw.println("    Print this help text.");
        pw.println("");
        pw.println("  compile [-m MODE] [-f] TARGET-PACKAGE");
        pw.println("    Trigger compilation of TARGET-PACKAGE.");
        pw.println("    Options:");
        pw.println("      -m: select compilation mode");
        pw.println("          MODE can be one of \"default\", \"all\", \"profile\", and \"extract\"");
        pw.println("      -f: force compilation even if not needed");
        pw.println("  list features");
        pw.println("    Prints all features of the system.");
        pw.println("  list instrumentation [-f] [TARGET-PACKAGE]");