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

Commit 0c9ef619 authored by Calin Juravle's avatar Calin Juravle Committed by Android (Google) Code Review
Browse files

Merge "Better handling of various types of compilation in DexOptimizer" into nyc-dev

parents a38b7c18 693f997c
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -4690,9 +4690,6 @@ public class PackageParser {
        // preferred up order.
        public int mPreferredOrder = 0;

        // For use by package manager to keep track of where it needs to do dexopt.
        public final ArraySet<String> mDexOptPerformed = new ArraySet<>(4);

        // For use by package manager to keep track of when a package was last used.
        public long mLastPackageUsageTimeInMills;

+3 −3
Original line number Diff line number Diff line
@@ -499,11 +499,11 @@ public class ZygoteInit {

        try {
            for (String classPathElement : classPathElements) {
                final int dexoptNeeded = DexFile.getDexOptNeeded(
                        classPathElement, "*", instructionSet, false /* defer */);
                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                // System server is fully AOTed and never profiled
                // for profile guided compilation.
                final int dexoptNeeded = DexFile.getDexOptNeeded(
                        classPathElement, instructionSet, DexFile.COMPILATION_TYPE_FULL);
                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                    installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
                            dexoptNeeded, 0 /*dexFlags*/, null /*volumeUuid*/,
                            false /*useProfiles*/);
+0 −5
Original line number Diff line number Diff line
@@ -180,10 +180,5 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
            return dexoptFlags | DEXOPT_OTA;
        }

        @Override
        protected void recordSuccessfulDexopt(Package pkg, String instructionSet) {
            // Never record the dexopt, as it's in the B partition.
        }

    }
}
+30 −57
Original line number Diff line number Diff line
@@ -112,15 +112,6 @@ class PackageDexOptimizer {
        }
    }

    /**
     * Determine whether the package should be skipped for the given instruction set. A return
     * value of true means the package will be skipped. A return value of false means that the
     * package will be further investigated, and potentially compiled.
     */
    protected boolean shouldSkipBasedOnISA(PackageParser.Package pkg, String instructionSet) {
        return pkg.mDexOptPerformed.contains(instructionSet);
    }

    /**
     * Adjust the given dexopt-needed value. Can be overridden to influence the decision to
     * optimize or not (and in what way).
@@ -136,13 +127,6 @@ class PackageDexOptimizer {
        return dexoptFlags;
    }

    /**
     * Update the package status after a successful compilation.
     */
    protected void recordSuccessfulDexopt(PackageParser.Package pkg, String instructionSet) {
        pkg.mDexOptPerformed.add(instructionSet);
    }

    private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
            boolean useProfiles, boolean extractOnly) {
        final String[] instructionSets = targetInstructionSets != null ?
@@ -159,11 +143,6 @@ class PackageDexOptimizer {
        boolean performedDexOpt = false;
        final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
        for (String dexCodeInstructionSet : dexCodeInstructionSets) {
            if (!useProfiles && shouldSkipBasedOnISA(pkg, dexCodeInstructionSet)) {
                // Skip only if we do not use profiles since they might trigger a recompilation.
                continue;
            }

            for (String path : paths) {
                if (useProfiles && isUsedByOtherApps(path)) {
                    // We cannot use profile guided compilation if the apk was used by another app.
@@ -172,35 +151,44 @@ class PackageDexOptimizer {
                int dexoptNeeded;

                try {
                    dexoptNeeded = DexFile.getDexOptNeeded(path, pkg.packageName,
                            dexCodeInstructionSet, /* defer */false);
                    int compilationTypeMask = 0;
                    if (extractOnly) {
                        // For extract only, any type of compilation is good.
                        compilationTypeMask = DexFile.COMPILATION_TYPE_FULL
                            | DexFile.COMPILATION_TYPE_PROFILE_GUIDE
                            | DexFile.COMPILATION_TYPE_EXTRACT_ONLY;
                    } else {
                        // Branch taken for profile guide and full compilation.
                        // Profile guide compilation should only recompile a previous
                        // profile compiled/extract only file and should not be attempted if the
                        // apk is already fully compiled. So test against a full compilation type.
                        compilationTypeMask = DexFile.COMPILATION_TYPE_FULL;
                    }
                    dexoptNeeded = DexFile.getDexOptNeeded(path,
                            dexCodeInstructionSet, compilationTypeMask);
                } catch (IOException ioe) {
                    Slog.w(TAG, "IOException reading apk: " + path, ioe);
                    return DEX_OPT_FAILED;
                }
                dexoptNeeded = adjustDexoptNeeded(dexoptNeeded);

                if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
                    if (useProfiles) {
                        // Profiles may trigger re-compilation. The final decision is taken in
                        // installd.
                        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) {
                switch (dexoptNeeded) {
                    case DexFile.NO_DEXOPT_NEEDED:
                        continue;
                    case DexFile.DEX2OAT_NEEDED:
                        dexoptType = "dex2oat";
                        oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet);
                } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) {
                        break;
                    case DexFile.PATCHOAT_NEEDED:
                        dexoptType = "patchoat";
                } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) {
                        break;
                    case DexFile.SELF_PATCHOAT_NEEDED:
                        dexoptType = "self patchoat";
                } else {
                    throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
                        break;
                    default:
                        throw new IllegalStateException("Invalid dexopt:" + dexoptNeeded);
                }


@@ -226,15 +214,6 @@ class PackageDexOptimizer {
                    Slog.w(TAG, "Failed to dexopt", e);
                }
            }

            if (!extractOnly) {
                // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
                // 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.
                recordSuccessfulDexopt(pkg, dexCodeInstructionSet);
            }
        }

        // If we've gotten here, we're sure that no error occurred and that we haven't
@@ -316,12 +295,6 @@ class PackageDexOptimizer {
            super(from);
        }

        @Override
        protected boolean shouldSkipBasedOnISA(Package pkg, String instructionSet) {
            // Forced compilation, never skip.
            return false;
        }

        @Override
        protected int adjustDexoptNeeded(int dexoptNeeded) {
            // Ensure compilation, no matter the current state.
+17 −26
Original line number Diff line number Diff line
@@ -639,9 +639,6 @@ public class PackageManagerService extends IPackageManager.Stub {
    // List of packages names to keep cached, even if they are uninstalled for all users
    private List<String> mKeepUninstalledPackages;
    private boolean mUseJitProfiles =
            SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
    private static class IFVerificationParams {
        PackageParser.Package pkg;
        boolean replacing;
@@ -2161,10 +2158,12 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                        try {
                            int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                            // Shared libraries do not have profiles so we perform a full
                                // AOT compilation.
                            // AOT compilation (if needed).
                            int dexoptNeeded = DexFile.getDexOptNeeded(
                                    lib, dexCodeInstructionSet,
                                    DexFile.COMPILATION_TYPE_FULL);
                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                                mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
                                        StorageManager.UUID_PRIVATE_INTERNAL,
@@ -6838,7 +6837,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        // Extract pacakges only if profile-guided compilation is enabled because
        // otherwise BackgroundDexOptService will not dexopt them later.
        if (!mUseJitProfiles || !isUpgrade()) {
        if (!isUpgrade()) {
            return;
        }
@@ -6920,10 +6919,6 @@ public class PackageManagerService extends IPackageManager.Stub {
            targetInstructionSet = instructionSet != null ? instructionSet :
                    getPrimaryInstructionSet(p.applicationInfo);
            if (!force && !useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) {
                // Skip only if we do not use profiles since they might trigger a recompilation.
                return false;
            }
        }
        long callingId = Binder.clearCallingIdentity();
        try {
@@ -13853,10 +13848,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                return;
            }
            // Extract package to save the VM unzipping the APK in memory during
            // launch. Only do this if profile-guided compilation is enabled because
            // otherwise BackgroundDexOptService will not dexopt the package later.
            if (mUseJitProfiles) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
            // Do not run PackageDexOptimizer through the local performDexOpt
            // method because `pkg` is not in `mPackages` yet.
@@ -13869,7 +13861,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                return;
            }
        }
        }
        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");