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

Commit 3b75828a authored by Calin Juravle's avatar Calin Juravle
Browse files

Extend profile analysis with proper return codes

This allows us to fine tune the optimization strategy when
profiles are empty.

Test: atest installd_dexopt_test
Bug: 188655918
Change-Id: Iaf782eedd92dfddd522feaecb446c85f3ae1c51e
(cherry picked from commit e90de86f)
parent a9b47394
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -2357,7 +2357,7 @@ binder::Status InstalldNativeService::copySystemProfile(const std::string& syste


// TODO: Consider returning error codes.
// TODO: Consider returning error codes.
binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
binder::Status InstalldNativeService::mergeProfiles(int32_t uid, const std::string& packageName,
        const std::string& profileName, bool* _aidl_return) {
        const std::string& profileName, int* _aidl_return) {
    ENFORCE_UID(AID_SYSTEM);
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
    std::lock_guard<std::recursive_mutex> lock(mLock);
    std::lock_guard<std::recursive_mutex> lock(mLock);
+1 −1
Original line number Original line Diff line number Diff line
@@ -125,7 +125,7 @@ public:
    binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);
    binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);


    binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
    binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
            const std::string& profileName, bool* _aidl_return);
            const std::string& profileName, int* _aidl_return);
    binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
    binder::Status dumpProfiles(int32_t uid, const std::string& packageName,
            const std::string& profileName, const std::string& codePath, bool* _aidl_return);
            const std::string& profileName, const std::string& codePath, bool* _aidl_return);
    binder::Status copySystemProfile(const std::string& systemProfile,
    binder::Status copySystemProfile(const std::string& systemProfile,
+1 −1
Original line number Original line Diff line number Diff line
@@ -69,7 +69,7 @@ interface IInstalld {


    void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet);
    void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet);


    boolean mergeProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName);
    int mergeProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String profileName);
    boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String  profileName,
    boolean dumpProfiles(int uid, @utf8InCpp String packageName, @utf8InCpp String  profileName,
            @utf8InCpp String codePath);
            @utf8InCpp String codePath);
    boolean copySystemProfile(@utf8InCpp String systemProfile, int uid,
    boolean copySystemProfile(@utf8InCpp String systemProfile, int uid,
+41 −26
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@
#include "execv_helper.h"
#include "execv_helper.h"
#include "globals.h"
#include "globals.h"
#include "installd_deps.h"
#include "installd_deps.h"
#include "installd_constants.h"
#include "otapreopt_utils.h"
#include "otapreopt_utils.h"
#include "run_dex2oat.h"
#include "run_dex2oat.h"
#include "unique_file.h"
#include "unique_file.h"
@@ -416,11 +417,12 @@ static void open_profile_files(uid_t uid, const std::string& package_name,


static constexpr int PROFMAN_BIN_RETURN_CODE_SUCCESS = 0;
static constexpr int PROFMAN_BIN_RETURN_CODE_SUCCESS = 0;
static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 1;
static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 1;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 2;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_NOT_ENOUGH_DELTA = 2;
static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 3;
static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 3;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 4;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 4;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 5;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 5;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_DIFFERENT_VERSIONS = 6;
static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_DIFFERENT_VERSIONS = 6;
static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_EMPTY_PROFILES = 7;


class RunProfman : public ExecVHelper {
class RunProfman : public ExecVHelper {
  public:
  public:
@@ -555,15 +557,7 @@ class RunProfman : public ExecVHelper {
    std::vector<unique_fd> apk_fds_;
    std::vector<unique_fd> apk_fds_;
};
};



static int analyze_profiles(uid_t uid, const std::string& package_name,

// Decides if profile guided compilation is needed or not based on existing profiles.
// The location is the package name for primary apks or the dex path for secondary dex files.
// Returns true if there is enough information in the current profiles that makes it
// worth to recompile the given location.
// If the return value is true all the current profiles would have been merged into
// the reference profiles accessible with open_reference_profile().
static bool analyze_profiles(uid_t uid, const std::string& package_name,
        const std::string& location, bool is_secondary_dex) {
        const std::string& location, bool is_secondary_dex) {
    std::vector<unique_fd> profiles_fd;
    std::vector<unique_fd> profiles_fd;
    unique_fd reference_profile_fd;
    unique_fd reference_profile_fd;
@@ -572,7 +566,7 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
    if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
        // Skip profile guided compilation because no profiles were found.
        // Skip profile guided compilation because no profiles were found.
        // Or if the reference profile info couldn't be opened.
        // Or if the reference profile info couldn't be opened.
        return false;
        return PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES;
    }
    }


    RunProfman profman_merge;
    RunProfman profman_merge;
@@ -594,6 +588,7 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    /* parent */
    /* parent */
    int return_code = wait_child(pid);
    int return_code = wait_child(pid);
    bool need_to_compile = false;
    bool need_to_compile = false;
    bool empty_profiles = false;
    bool should_clear_current_profiles = false;
    bool should_clear_current_profiles = false;
    bool should_clear_reference_profile = false;
    bool should_clear_reference_profile = false;
    if (!WIFEXITED(return_code)) {
    if (!WIFEXITED(return_code)) {
@@ -606,8 +601,14 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
                should_clear_current_profiles = true;
                should_clear_current_profiles = true;
                should_clear_reference_profile = false;
                should_clear_reference_profile = false;
                break;
                break;
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_NOT_ENOUGH_DELTA:
                need_to_compile = false;
                should_clear_current_profiles = false;
                should_clear_reference_profile = false;
                break;
            case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION_EMPTY_PROFILES:
                need_to_compile = false;
                need_to_compile = false;
                empty_profiles = true;
                should_clear_current_profiles = false;
                should_clear_current_profiles = false;
                should_clear_reference_profile = false;
                should_clear_reference_profile = false;
                break;
                break;
@@ -653,16 +654,29 @@ static bool analyze_profiles(uid_t uid, const std::string& package_name,
    if (should_clear_reference_profile) {
    if (should_clear_reference_profile) {
        clear_reference_profile(package_name, location, is_secondary_dex);
        clear_reference_profile(package_name, location, is_secondary_dex);
    }
    }
    return need_to_compile;
    int result = 0;
    if (need_to_compile) {
        result = PROFILES_ANALYSIS_OPTIMIZE;
    } else if (empty_profiles) {
        result = PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES;
    } else {
        result = PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA;
    }
    return result;
}
}


// Decides if profile guided compilation is needed or not based on existing profiles.
// Decides if profile guided compilation is needed or not based on existing profiles.
// The analysis is done for the primary apks of the given package.
// The analysis is done for a single profile name (which corresponds to a single code path).
// Returns true if there is enough information in the current profiles that makes it
//
// worth to recompile the package.
// Returns PROFILES_ANALYSIS_OPTIMIZE if there is enough information in the current profiles
// If the return value is true all the current profiles would have been merged into
// that makes it worth to recompile the package.
// the reference profiles accessible with open_reference_profile().
// If the return value is PROFILES_ANALYSIS_OPTIMIZE all the current profiles would have been
bool analyze_primary_profiles(uid_t uid, const std::string& package_name,
// merged into the reference profiles accessible with open_reference_profile().
//
// Return PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA if the package should not optimize.
// As a special case returns PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES if all profiles are
// empty.
int analyze_primary_profiles(uid_t uid, const std::string& package_name,
        const std::string& profile_name) {
        const std::string& profile_name) {
    return analyze_profiles(uid, package_name, profile_name, /*is_secondary_dex*/false);
    return analyze_profiles(uid, package_name, profile_name, /*is_secondary_dex*/false);
}
}
@@ -1166,7 +1180,7 @@ class RunDexoptAnalyzer : public ExecVHelper {
                      int zip_fd,
                      int zip_fd,
                      const std::string& instruction_set,
                      const std::string& instruction_set,
                      const std::string& compiler_filter,
                      const std::string& compiler_filter,
                      bool profile_was_updated,
                      int profile_analysis_result,
                      bool downgrade,
                      bool downgrade,
                      const char* class_loader_context,
                      const char* class_loader_context,
                      const std::string& class_loader_context_fds) {
                      const std::string& class_loader_context_fds) {
@@ -1182,7 +1196,8 @@ class RunDexoptAnalyzer : public ExecVHelper {
        std::string zip_fd_arg = "--zip-fd=" + std::to_string(zip_fd);
        std::string zip_fd_arg = "--zip-fd=" + std::to_string(zip_fd);
        std::string isa_arg = "--isa=" + instruction_set;
        std::string isa_arg = "--isa=" + instruction_set;
        std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter;
        std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter;
        const char* assume_profile_changed = "--assume-profile-changed";
        std::string profile_analysis_arg = "--profile-analysis-result="
                + std::to_string(profile_analysis_result);
        const char* downgrade_flag = "--downgrade";
        const char* downgrade_flag = "--downgrade";
        std::string class_loader_context_arg = "--class-loader-context=";
        std::string class_loader_context_arg = "--class-loader-context=";
        if (class_loader_context != nullptr) {
        if (class_loader_context != nullptr) {
@@ -1204,9 +1219,8 @@ class RunDexoptAnalyzer : public ExecVHelper {
            AddArg(vdex_fd_arg);
            AddArg(vdex_fd_arg);
        }
        }
        AddArg(zip_fd_arg);
        AddArg(zip_fd_arg);
        if (profile_was_updated) {
        AddArg(profile_analysis_arg);
            AddArg(assume_profile_changed);

        }
        if (downgrade) {
        if (downgrade) {
            AddArg(downgrade_flag);
            AddArg(downgrade_flag);
        }
        }
@@ -1578,7 +1592,7 @@ static bool process_secondary_dex_dexopt(const std::string& dex_path, const char
        }
        }


        // Analyze profiles.
        // Analyze profiles.
        bool profile_was_updated = analyze_profiles(uid, pkgname, dex_path,
        int profile_analysis_result = analyze_profiles(uid, pkgname, dex_path,
                /*is_secondary_dex*/true);
                /*is_secondary_dex*/true);


        // Run dexoptanalyzer to get dexopt_needed code. This is not expected to return.
        // Run dexoptanalyzer to get dexopt_needed code. This is not expected to return.
@@ -1589,7 +1603,8 @@ static bool process_secondary_dex_dexopt(const std::string& dex_path, const char
                                              oat_file_fd.get(),
                                              oat_file_fd.get(),
                                              zip_fd.get(),
                                              zip_fd.get(),
                                              instruction_set,
                                              instruction_set,
                                              compiler_filter, profile_was_updated,
                                              compiler_filter,
                                              profile_analysis_result,
                                              downgrade,
                                              downgrade,
                                              class_loader_context,
                                              class_loader_context,
                                              join_fds(context_zip_fds));
                                              join_fds(context_zip_fds));
+13 −8
Original line number Original line Diff line number Diff line
@@ -54,13 +54,18 @@ bool clear_primary_current_profile(const std::string& pkgname, const std::string
// Clear all current profiles identified by the given profile name (all users).
// Clear all current profiles identified by the given profile name (all users).
bool clear_primary_current_profiles(const std::string& pkgname, const std::string& profile_name);
bool clear_primary_current_profiles(const std::string& pkgname, const std::string& profile_name);


// Decide if profile guided compilation is needed or not based on existing profiles.
// Decides if profile guided compilation is needed or not based on existing profiles.
// The analysis is done for a single profile name (which corresponds to a single code path).
// The analysis is done for a single profile name (which corresponds to a single code path).
// Returns true if there is enough information in the current profiles that makes it
//
// worth to recompile the package.
// Returns PROFILES_ANALYSIS_OPTIMIZE if there is enough information in the current profiles
// If the return value is true all the current profiles would have been merged into
// that makes it worth to recompile the package.
// the reference profiles accessible with open_reference_profile().
// If the return value is PROFILES_ANALYSIS_OPTIMIZE all the current profiles would have been
bool analyze_primary_profiles(uid_t uid,
// merged into the reference profiles accessible with open_reference_profile().
//
// Return PROFILES_ANALYSIS_DONT_OPTIMIZE_SMALL_DELTA if the package should not optimize.
// As a special case returns PROFILES_ANALYSIS_DONT_OPTIMIZE_EMPTY_PROFILES if all profiles are
// empty.
int analyze_primary_profiles(uid_t uid,
                             const std::string& pkgname,
                             const std::string& pkgname,
                             const std::string& profile_name);
                             const std::string& profile_name);


Loading