Home | History | Annotate | Download | only in library_loader
      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