mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
bug 623999 - Takes 35s to start up r=dougt f=taras a=blocking-fennec
This commit is contained in:
parent
edb072f038
commit
9d589f4402
@ -194,26 +194,6 @@ find_cdir_entry (struct cdir_entry *entry, int count, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t simple_write(int fd, const void *buf, uint32_t count)
|
||||
{
|
||||
uint32_t out_offset = 0;
|
||||
while (out_offset < count) {
|
||||
uint32_t written = write(fd, buf + out_offset,
|
||||
count - out_offset);
|
||||
if (written == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
continue;
|
||||
else {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "simple_write failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out_offset += written;
|
||||
}
|
||||
return out_offset;
|
||||
}
|
||||
|
||||
#define SHELL_WRAPPER0(name) \
|
||||
typedef void (*name ## _t)(JNIEnv *, jclass); \
|
||||
static name ## _t f_ ## name; \
|
||||
@ -267,6 +247,31 @@ extern "C" int extractLibs = 1;
|
||||
extern "C" int extractLibs = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_EXTRACT_LIBS 1
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_EXTRACT_LIBS
|
||||
static uint32_t simple_write(int fd, const void *buf, uint32_t count)
|
||||
{
|
||||
uint32_t out_offset = 0;
|
||||
while (out_offset < count) {
|
||||
uint32_t written = write(fd, buf + out_offset,
|
||||
count - out_offset);
|
||||
if (written == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
continue;
|
||||
else {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "simple_write failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out_offset += written;
|
||||
}
|
||||
return out_offset;
|
||||
}
|
||||
|
||||
static void
|
||||
extractFile(const char * path, const struct cdir_entry *entry, void * data)
|
||||
{
|
||||
@ -326,6 +331,7 @@ extractFile(const char * path, const struct cdir_entry *entry, void * data)
|
||||
close(fd);
|
||||
munmap(buf, 4096);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
extractLib(const struct cdir_entry *entry, void * data, void * dest)
|
||||
@ -422,13 +428,15 @@ lookupLibCacheFd(const char *libName)
|
||||
}
|
||||
|
||||
static void
|
||||
addLibCacheFd(const char *libName, int fd)
|
||||
addLibCacheFd(const char *libName, int fd, uint32_t lib_size = 0, void* buffer = NULL)
|
||||
{
|
||||
ensureLibCache();
|
||||
|
||||
struct lib_cache_info *info = &cache_mapping[cache_count++];
|
||||
strncpy(info->name, libName, MAX_LIB_CACHE_NAME_LEN - 1);
|
||||
info->fd = fd;
|
||||
info->lib_size = lib_size;
|
||||
info->buffer = buffer;
|
||||
}
|
||||
|
||||
static void * mozload(const char * path, void *zip,
|
||||
@ -444,6 +452,7 @@ static void * mozload(const char * path, void *zip,
|
||||
void * data = ((void *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
|
||||
void * handle;
|
||||
|
||||
#ifdef DEBUG_EXTRACT_LIBS
|
||||
if (extractLibs) {
|
||||
char fullpath[256];
|
||||
snprintf(fullpath, 256, "%s/%s", getenv("CACHE_PATH"), path + 4);
|
||||
@ -462,14 +471,15 @@ static void * mozload(const char * path, void *zip,
|
||||
#endif
|
||||
return handle;
|
||||
}
|
||||
|
||||
#endif
|
||||
size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
|
||||
|
||||
int fd = zip_fd;
|
||||
void * buf = NULL;
|
||||
uint32_t lib_size = letoh32(entry->uncompressed_size);
|
||||
int cache_fd = 0;
|
||||
if (letoh16(file->compression) == DEFLATE) {
|
||||
int cache_fd = lookupLibCacheFd(path + 4);
|
||||
cache_fd = lookupLibCacheFd(path + 4);
|
||||
fd = cache_fd;
|
||||
if (fd < 0) {
|
||||
char fullpath[256];
|
||||
@ -478,8 +488,13 @@ static void * mozload(const char * path, void *zip,
|
||||
struct stat status;
|
||||
if (stat(fullpath, &status) ||
|
||||
status.st_size != lib_size ||
|
||||
apk_mtime > status.st_mtime)
|
||||
apk_mtime > status.st_mtime) {
|
||||
unlink(fullpath);
|
||||
fd = -1;
|
||||
} else {
|
||||
cache_fd = fd;
|
||||
addLibCacheFd(path + 4, fd);
|
||||
}
|
||||
}
|
||||
if (fd < 0)
|
||||
fd = createAshmem(lib_size, path);
|
||||
@ -504,8 +519,11 @@ static void * mozload(const char * path, void *zip,
|
||||
|
||||
if (cache_fd < 0) {
|
||||
extractLib(entry, data, buf);
|
||||
addLibCacheFd(path + 4, fd);
|
||||
addLibCacheFd(path + 4, fd, lib_size, buf);
|
||||
}
|
||||
// preload libxul, to avoid slowly demand-paging it
|
||||
if (!strcmp(path, "lib/libxul.so"))
|
||||
madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
|
||||
data = buf;
|
||||
}
|
||||
|
||||
@ -517,7 +535,10 @@ static void * mozload(const char * path, void *zip,
|
||||
lib_size, offset);
|
||||
if (!handle)
|
||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", path, __wrap_dlerror());
|
||||
if (buf)
|
||||
|
||||
// if we're extracting the libs to disk and cache_fd is not valid then
|
||||
// keep this buffer around so it can be used to write to disk
|
||||
if (buf && (!extractLibs || cache_fd >= 0))
|
||||
munmap(buf, lib_size);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -670,6 +691,36 @@ Java_org_mozilla_gecko_GeckoAppShell_loadLibs(JNIEnv *jenv, jclass jGeckoAppShel
|
||||
|
||||
loadLibs(str);
|
||||
jenv->ReleaseStringUTFChars(jApkName, str);
|
||||
if (extractLibs && cache_mapping) {
|
||||
if (!fork()) {
|
||||
sleep(10);
|
||||
nice(10);
|
||||
int count = cache_count;
|
||||
while (count--) {
|
||||
struct lib_cache_info *info = &cache_mapping[count];
|
||||
if (!info->buffer)
|
||||
continue;
|
||||
|
||||
char fullpath[256];
|
||||
snprintf(fullpath, 256, "%s/%s", getenv("CACHE_PATH"), info->name);
|
||||
char tmp_path[256];
|
||||
sprintf(tmp_path, "%s.tmp", fullpath);
|
||||
int file_fd = open(tmp_path, O_CREAT | O_WRONLY);
|
||||
// using sendfile would be preferable, but it doesn't seem to work
|
||||
// with shared memory on any of the devices we've tested
|
||||
uint32_t sent = write(file_fd, info->buffer, info->lib_size);
|
||||
|
||||
munmap(info->buffer, info->lib_size);
|
||||
info->buffer = 0;
|
||||
close(file_fd);
|
||||
if (sent == info->lib_size)
|
||||
rename(tmp_path, fullpath);
|
||||
else
|
||||
unlink(tmp_path);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef int GeckoProcessType;
|
||||
|
@ -53,6 +53,8 @@ const struct mapping_info * getLibraryMapping();
|
||||
struct lib_cache_info {
|
||||
char name[MAX_LIB_CACHE_NAME_LEN];
|
||||
int fd;
|
||||
uint32_t lib_size;
|
||||
void* buffer;
|
||||
};
|
||||
|
||||
const struct lib_cache_info * getLibraryCache();
|
||||
|
@ -54,8 +54,10 @@ static void set_dlerror(int err)
|
||||
|
||||
void *__wrap_dlopen(const char *filename, int flag)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (extractLibs)
|
||||
return dlopen(filename, flag);
|
||||
#endif
|
||||
|
||||
soinfo *ret;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user