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