Installd: Swap file for dex2oat
Add swap file support for dex2oat to installd. Only use in low-memory
mode.
Bug: 18596910
(cherry picked from commit f68ce4de7f
)
Change-Id: I131448f3907115054a592af73db86d2b9257ea33
This commit is contained in:
parent
1be4021c2a
commit
e1c01353c4
@ -696,7 +696,7 @@ static void run_patchoat(int input_fd, int oat_fd, const char* input_file_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
||||||
const char* output_file_name, const char *pkgname, const char *instruction_set,
|
const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set,
|
||||||
bool vm_safe_mode)
|
bool vm_safe_mode)
|
||||||
{
|
{
|
||||||
static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
|
static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
|
||||||
@ -762,6 +762,8 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
|||||||
char dex2oat_Xms_arg[strlen("-Xms") + PROPERTY_VALUE_MAX];
|
char dex2oat_Xms_arg[strlen("-Xms") + PROPERTY_VALUE_MAX];
|
||||||
char dex2oat_Xmx_arg[strlen("-Xmx") + PROPERTY_VALUE_MAX];
|
char dex2oat_Xmx_arg[strlen("-Xmx") + PROPERTY_VALUE_MAX];
|
||||||
char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + PROPERTY_VALUE_MAX];
|
char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + PROPERTY_VALUE_MAX];
|
||||||
|
bool have_dex2oat_swap_fd = false;
|
||||||
|
char dex2oat_swap_fd[strlen("--swap-fd=") + MAX_INT_LEN];
|
||||||
|
|
||||||
sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
|
sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
|
||||||
sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
|
sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
|
||||||
@ -770,6 +772,10 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
|||||||
sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
|
sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
|
||||||
sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant);
|
sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant);
|
||||||
sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features);
|
sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features);
|
||||||
|
if (swap_fd >= 0) {
|
||||||
|
have_dex2oat_swap_fd = true;
|
||||||
|
sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd);
|
||||||
|
}
|
||||||
|
|
||||||
bool have_profile_file = false;
|
bool have_profile_file = false;
|
||||||
bool have_top_k_profile_threshold = false;
|
bool have_top_k_profile_threshold = false;
|
||||||
@ -815,6 +821,7 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
|||||||
+ (have_dex2oat_Xms_flag ? 2 : 0)
|
+ (have_dex2oat_Xms_flag ? 2 : 0)
|
||||||
+ (have_dex2oat_Xmx_flag ? 2 : 0)
|
+ (have_dex2oat_Xmx_flag ? 2 : 0)
|
||||||
+ (have_dex2oat_compiler_filter_flag ? 1 : 0)
|
+ (have_dex2oat_compiler_filter_flag ? 1 : 0)
|
||||||
|
+ (have_dex2oat_swap_fd ? 1 : 0)
|
||||||
+ dex2oat_flags_count];
|
+ dex2oat_flags_count];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
argv[i++] = (char*)DEX2OAT_BIN;
|
argv[i++] = (char*)DEX2OAT_BIN;
|
||||||
@ -846,6 +853,9 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
|
|||||||
if (have_dex2oat_compiler_filter_flag) {
|
if (have_dex2oat_compiler_filter_flag) {
|
||||||
argv[i++] = dex2oat_compiler_filter_arg;
|
argv[i++] = dex2oat_compiler_filter_arg;
|
||||||
}
|
}
|
||||||
|
if (have_dex2oat_swap_fd) {
|
||||||
|
argv[i++] = dex2oat_swap_fd;
|
||||||
|
}
|
||||||
if (dex2oat_flags_count) {
|
if (dex2oat_flags_count) {
|
||||||
i += split(dex2oat_flags, argv + i);
|
i += split(dex2oat_flags, argv + i);
|
||||||
}
|
}
|
||||||
@ -882,6 +892,23 @@ static int wait_child(pid_t pid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Whether dexopt should use a swap file when compiling an APK. If kAlwaysProvideSwapFile, do this
|
||||||
|
* on all devices (dex2oat will make a more informed decision itself, anyways). Otherwise, only do
|
||||||
|
* this on a low-mem device.
|
||||||
|
*/
|
||||||
|
static bool kAlwaysProvideSwapFile = true;
|
||||||
|
|
||||||
|
static bool ShouldUseSwapFileForDexopt() {
|
||||||
|
if (kAlwaysProvideSwapFile) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char low_mem_buf[PROPERTY_VALUE_MAX];
|
||||||
|
property_get("ro.config.low_ram", low_mem_buf, "");
|
||||||
|
return (strcmp(low_mem_buf, "true") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
||||||
const char *pkgname, const char *instruction_set,
|
const char *pkgname, const char *instruction_set,
|
||||||
bool vm_safe_mode, bool is_patchoat)
|
bool vm_safe_mode, bool is_patchoat)
|
||||||
@ -889,11 +916,15 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
|||||||
struct utimbuf ut;
|
struct utimbuf ut;
|
||||||
struct stat input_stat, dex_stat;
|
struct stat input_stat, dex_stat;
|
||||||
char out_path[PKG_PATH_MAX];
|
char out_path[PKG_PATH_MAX];
|
||||||
|
char swap_file_name[PKG_PATH_MAX];
|
||||||
char *end;
|
char *end;
|
||||||
const char *input_file;
|
const char *input_file;
|
||||||
char in_odex_path[PKG_PATH_MAX];
|
char in_odex_path[PKG_PATH_MAX];
|
||||||
int res, input_fd=-1, out_fd=-1;
|
int res, input_fd=-1, out_fd=-1, swap_fd=-1;
|
||||||
|
|
||||||
|
// Early best-effort check whether we can fit the the path into our buffers.
|
||||||
|
// Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
|
||||||
|
// without a swap file, if necessary.
|
||||||
if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
|
if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -968,6 +999,28 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
|||||||
create_profile_file(pkgname, uid);
|
create_profile_file(pkgname, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a swap file if necessary.
|
||||||
|
if (!is_patchoat && ShouldUseSwapFileForDexopt()) {
|
||||||
|
// Make sure there really is enough space.
|
||||||
|
size_t out_len = strlen(out_path);
|
||||||
|
if (out_len + strlen(".swap") + 1 <= PKG_PATH_MAX) {
|
||||||
|
strcpy(swap_file_name, out_path);
|
||||||
|
strcpy(swap_file_name + strlen(out_path), ".swap");
|
||||||
|
unlink(swap_file_name);
|
||||||
|
swap_fd = open(swap_file_name, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
if (swap_fd < 0) {
|
||||||
|
// Could not create swap file. Optimistically go on and hope that we can compile
|
||||||
|
// without it.
|
||||||
|
ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
|
||||||
|
} else {
|
||||||
|
// Immediately unlink. We don't really want to hit flash.
|
||||||
|
unlink(swap_file_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Swap file path is too long. Try to run without.
|
||||||
|
ALOGE("installd could not create swap file for path %s during dexopt\n", out_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
|
ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
|
||||||
|
|
||||||
@ -1005,7 +1058,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
|||||||
if (is_patchoat) {
|
if (is_patchoat) {
|
||||||
run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
|
run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
|
||||||
} else {
|
} else {
|
||||||
run_dex2oat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set,
|
run_dex2oat(input_fd, out_fd, input_file, out_path, swap_fd, pkgname, instruction_set,
|
||||||
vm_safe_mode);
|
vm_safe_mode);
|
||||||
}
|
}
|
||||||
exit(68); /* only get here on exec failure */
|
exit(68); /* only get here on exec failure */
|
||||||
@ -1025,6 +1078,9 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public,
|
|||||||
|
|
||||||
close(out_fd);
|
close(out_fd);
|
||||||
close(input_fd);
|
close(input_fd);
|
||||||
|
if (swap_fd != -1) {
|
||||||
|
close(swap_fd);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
Loading…
Reference in New Issue
Block a user