1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2015 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_ 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_ 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <jni.h> 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <string> 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/debug/proc_maps_linux.h" 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/gtest_prod_util.h" 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace base { 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace android { 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Forks and waits for a process prefetching the native library. This is done in 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// a forked process for the following reasons: 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// - Isolating the main process from mistakes in the parsing. If the parsing 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// returns an incorrect address, only the forked process will crash. 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// - Not inflating the memory used by the main process uselessly, which could 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// increase its likelihood to be killed. 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// The forked process has background priority and, since it is not declared to 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// the Android runtime, can be killed at any time, which is not an issue here. 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass BASE_EXPORT NativeLibraryPrefetcher { 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Finds the ranges matching the native library, forks a low priority 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // process pre-fetching these ranges and wait()s for it. 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns true for success. 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static bool ForkAndPrefetchNativeLibrary(); 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns the percentage of the native library code currently resident in 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // memory, or -1 in case of error. 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static int PercentageOfResidentNativeLibraryCode(); 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez using AddressRange = std::pair<uintptr_t, uintptr_t>; 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns true if the region matches native code or data. 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static bool IsGoodToPrefetch(const base::debug::MappedMemoryRegion& region); 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Filters the regions to keep only libchrome ranges if possible. 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static void FilterLibchromeRangesOnlyIfPossible( 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const std::vector<base::debug::MappedMemoryRegion>& regions, 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::vector<AddressRange>* ranges); 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Finds the ranges matching the native library in /proc/self/maps. 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns true for success. 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static bool FindRanges(std::vector<AddressRange>* ranges); 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns the percentage of the given address ranges currently resident in 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // memory, or -1 in case of error. 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static int PercentageOfResidentCode(const std::vector<AddressRange>& ranges); 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestIsGoodToPrefetchNoRange); 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestIsGoodToPrefetchUnreadableRange); 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestIsGoodToPrefetchSkipSharedRange); 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestIsGoodToPrefetchLibchromeRange); 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestIsGoodToPrefetchBaseApkRange); 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestFilterLibchromeRangesOnlyIfPossibleNoLibchrome); 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestFilterLibchromeRangesOnlyIfPossibleHasLibchrome); 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestPercentageOfResidentCode); 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez FRIEND_TEST_ALL_PREFIXES(NativeLibraryPrefetcherTest, 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez TestPercentageOfResidentCodeTwoRegions); 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_IMPLICIT_CONSTRUCTORS(NativeLibraryPrefetcher); 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace android 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace base 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif // BASE_ANDROID_LIBRARY_LOADER_LIBRARY_PREFETCHER_H_ 80