Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4f647e2 authored by Torne (Richard Coles)'s avatar Torne (Richard Coles)
Browse files

Preload with RELRO sharing in the WebView zygote.

Now that the WebView zygote is a child of the system zygote it has the
smae address space layout and can use the existing WebView native
library RELRO file.

Preload the native library using the RELRO file in the zygote, to share
this data with applications which are using WebView. This can save up to
1-2MB of dirty memory, replacing it with clean pages that are shared
with more processes and thus have a smaller impact on PSS.

Bug: 63749735
Test: CtsWebkitTests
Change-Id: I7ce670f5fcddae9e98631e21329840ef3ad52f9a
parent ec572f6a
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -493,11 +493,12 @@ public class ZygoteProcess {
     * Instructs the zygote to pre-load the classes and native libraries at the given paths
     * for the specified abi. Not all zygotes support this function.
     */
    public boolean preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
                                        String abi) throws ZygoteStartFailedEx, IOException {
    public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
                                        String cacheKey, String abi) throws ZygoteStartFailedEx,
                                                                            IOException {
        synchronized(mLock) {
            ZygoteState state = openZygoteSocketIfNeeded(abi);
            state.writer.write("4");
            state.writer.write("5");
            state.writer.newLine();

            state.writer.write("--preload-package");
@@ -509,6 +510,9 @@ public class ZygoteProcess {
            state.writer.write(libsPath);
            state.writer.newLine();

            state.writer.write(libFileName);
            state.writer.newLine();

            state.writer.write(cacheKey);
            state.writer.newLine();

+3 −1
Original line number Diff line number Diff line
@@ -169,6 +169,8 @@ public class WebViewZygote {
            final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
                    TextUtils.join(File.pathSeparator, zipPaths);

            String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo);

            // In the case where the ApplicationInfo has been modified by the stub WebView,
            // we need to use the original ApplicationInfo to determine what the original classpath
            // would have been to use as a cache key.
@@ -179,7 +181,7 @@ public class WebViewZygote {
            ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());

            Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
            sZygote.preloadPackageForAbi(zip, librarySearchPath, cacheKey,
            sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
                                         Build.SUPPORTED_ABIS[0]);
        } catch (Exception e) {
            Log.e(LOGTAG, "Error connecting to webview zygote", e);
+7 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebViewFactory;
import android.webkit.WebViewFactoryProvider;
import android.webkit.WebViewLibraryLoader;

import java.io.DataOutputStream;
import java.io.File;
@@ -71,7 +72,8 @@ class WebViewZygoteInit {
        }

        @Override
        protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
        protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
                String cacheKey) {
            Log.i(TAG, "Beginning package preload");
            // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
            // our children will reuse the same classloader instead of creating their own.
@@ -80,6 +82,10 @@ class WebViewZygoteInit {
            ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
                    packagePath, libsPath, cacheKey);

            // Load the native library using WebViewLibraryLoader to share the RELRO data with other
            // processes.
            WebViewLibraryLoader.loadNativeLibrary(loader, libFileName);

            // Add the APK to the Zygote's list of allowed files for children.
            String[] packageList = TextUtils.split(packagePath, File.pathSeparator);
            for (String packageEntry : packageList) {
+19 −3
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ class ZygoteConnection {

        if (parsedArgs.preloadPackage != null) {
            handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
                    parsedArgs.preloadPackageCacheKey);
                    parsedArgs.preloadPackageLibFileName, parsedArgs.preloadPackageCacheKey);
            return null;
        }

@@ -290,7 +290,8 @@ class ZygoteConnection {
        return mSocketOutStream;
    }

    protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
    protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
            String cacheKey) {
        throw new RuntimeException("Zyogte does not support package preloading");
    }

@@ -402,10 +403,24 @@ class ZygoteConnection {
        String appDataDir;

        /**
         * Whether to preload a package, with the package path in the remainingArgs.
         * The APK path of the package to preload, when using --preload-package.
         */
        String preloadPackage;

        /**
         * The native library path of the package to preload, when using --preload-package.
         */
        String preloadPackageLibs;

        /**
         * The filename of the native library to preload, when using --preload-package.
         */
        String preloadPackageLibFileName;

        /**
         * The cache key under which to enter the preloaded package into the classloader cache,
         * when using --preload-package.
         */
        String preloadPackageCacheKey;

        /**
@@ -571,6 +586,7 @@ class ZygoteConnection {
                } else if (arg.equals("--preload-package")) {
                    preloadPackage = args[++curArg];
                    preloadPackageLibs = args[++curArg];
                    preloadPackageLibFileName = args[++curArg];
                    preloadPackageCacheKey = args[++curArg];
                } else if (arg.equals("--preload-default")) {
                    preloadDefault = true;