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

Commit 7f842bab authored by Calin Juravle's avatar Calin Juravle Committed by android-build-merger
Browse files

Merge "Better handling of various types of compilation in DexOptimizer" into nyc-dev am: 0c9ef619

am: 44a39b00

* commit '44a39b00':
  Better handling of various types of compilation in DexOptimizer
parents a6913971 44a39b00
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");