Skip to content

Commit

Permalink
android: Prefetch the ordered section first.
Browse files Browse the repository at this point in the history
The section of .text covered by the orderfile is now located in the
middle of the binary, after the clang roll in r550608. This negatively
impacts startup performance as the prefetcher doesn't start by fetching
the early startup code.

This fixes it by fetching the ordered range first, then all of
.text. Fetching the ordered section twice should add almost no time, as
it is not even a minor page fault the second time.

Bug: 833299
Change-Id: Id71818a90552c85849b20624a4d144098c102a42
Reviewed-on: https://chromium-review.googlesource.com/1024032
Reviewed-by: Egor Pasko <pasko@chromium.org>
Reviewed-by: agrieve <agrieve@chromium.org>
Commit-Queue: Benoit L <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553032}
  • Loading branch information
Benoit Lize authored and Commit Bot committed Apr 24, 2018
1 parent f4ff4af commit f35f741
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions base/android/library_loader/library_prefetcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <unistd.h>
#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <memory>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -200,18 +201,22 @@ bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(bool ordered_only) {
// state of its parent thread. It cannot rely on being able to acquire any
// lock (unless special care is taken in a pre-fork handler), including being
// able to call malloc().
std::pair<size_t, size_t> range;
if (ordered_only) {
range = GetOrderedTextRange();
} else {
range = GetTextRange();
}
//
// Always prefetch the ordered section first, as it's reached early during
// startup, and not necessarily located at the beginning of .text.
std::vector<std::pair<size_t, size_t>> ranges = {GetOrderedTextRange()};
if (!ordered_only)
ranges.push_back(GetTextRange());

pid_t pid = fork();
if (pid == 0) {
setpriority(PRIO_PROCESS, 0, kBackgroundPriority);
// _exit() doesn't call the atexit() handlers.
_exit(Prefetch(range.first, range.second) ? 0 : 1);
for (const auto& range : ranges) {
if (!Prefetch(range.first, range.second))
_exit(EXIT_FAILURE);
}
_exit(EXIT_SUCCESS);
} else {
if (pid < 0) {
return false;
Expand All @@ -220,7 +225,7 @@ bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary(bool ordered_only) {
const pid_t result = HANDLE_EINTR(waitpid(pid, &status, 0));
if (result == pid) {
if (WIFEXITED(status)) {
return WEXITSTATUS(status) == 0;
return WEXITSTATUS(status) == EXIT_SUCCESS;
}
}
return false;
Expand Down

0 comments on commit f35f741

Please sign in to comment.