• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_
6 #define BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_
7 
8 #include <jni.h>
9 
10 #include <stdint.h>
11 #include <string>
12 
13 #include "base/debug/proc_maps_linux.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/macros.h"
16 
17 namespace base {
18 namespace android {
19 
20 // Forks and waits for a process prefetching the native library. This is done in
21 // a forked process for the following reasons:
22 // - Isolating the main process from mistakes in the parsing. If the parsing
23 //   returns an incorrect address, only the forked process will crash.
24 // - Not inflating the memory used by the main process uselessly, which could
25 //   increase its likelihood to be killed.
26 // The forked process has background priority and, since it is not declared to
27 // the Android runtime, can be killed at any time, which is not an issue here.
28 class BASE_EXPORT NativeLibraryPrefetcher {
29  public:
30   // Finds the ranges matching the native library, forks a low priority
31   // process pre-fetching these ranges and wait()s for it.
32   // Returns true for success.
33   static bool ForkAndPrefetchNativeLibrary();
34   // Returns the percentage of the native library code currently resident in
35   // memory, or -1 in case of error.
36   static int PercentageOfResidentNativeLibraryCode();
37 
38  private:
39   using AddressRange = std::pair<uintptr_t, uintptr_t>;
40   // Returns true if the region matches native code or data.
41   static bool IsGoodToPrefetch(const base::debug::MappedMemoryRegion& region);
42   // Filters the regions to keep only libchrome ranges if possible.
43   static void FilterLibchromeRangesOnlyIfPossible(
44       const std::vector<base::debug::MappedMemoryRegion>& regions,
45       std::vector<AddressRange>* ranges);
46   // Finds the ranges matching the native library in /proc/self/maps.
47   // Returns true for success.
48   static bool FindRanges(std::vector<AddressRange>* ranges);
49 
50   // Returns the percentage of the given address ranges currently resident in
51   // memory, or -1 in case of error.
52   static int PercentageOfResidentCode(const std::vector<AddressRange>& ranges);
53 
54   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
55                            TestIsGoodToPrefetchNoRange);
56   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
57                            TestIsGoodToPrefetchUnreadableRange);
58   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
59                            TestIsGoodToPrefetchSkipSharedRange);
60   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
61                            TestIsGoodToPrefetchLibchromeRange);
62   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
63                            TestIsGoodToPrefetchBaseApkRange);
64   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
65                            TestFilterLibchromeRangesOnlyIfPossibleNoLibchrome);
66   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
67                            TestFilterLibchromeRangesOnlyIfPossibleHasLibchrome);
68   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
69                            TestPercentageOfResidentCode);
70   FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest,
71                            TestPercentageOfResidentCodeTwoRegions);
72 
73   DISALLOW_IMPLICIT_CONSTRUCTORS(NativeLibraryPrefetcher);
74 };
75 
76 }  // namespace android
77 }  // namespace base
78 
79 #endif  // BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_
80