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

Commit 599c918d authored by Andy McFadden's avatar Andy McFadden Committed by The Android Open Source Project
Browse files

AI 144931: Added a (hidden) way to "pre-cache" register maps.

  The 50 methods that appeared on the GC stacks of the most applications
  require 13KB of native heap for their uncompressed register maps, and
  the full set took 5ms to uncompress.  Pre-computation doesn't represent
  a significant improvement in space or time, at the cost of a big pile
  of strings in ZygoteInit.
  I'm leaving the method in ZygoteInit, but it's not called, and the
  static final String[] of method descriptors is empty.  We may want to
  revisit this later.
  BUG=1729570

Automated import of CL 144931
parent 43f36930
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -632,6 +632,25 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo
     */
    public static final native int getBinderDeathObjectCount();

    /**
     * Primes the register map cache.
     *
     * Only works for classes in the bootstrap class loader.  Does not
     * cause classes to be loaded if they're not already present.
     *
     * The classAndMethodDesc argument is a concatentation of the VM-internal
     * class descriptor, method name, and method descriptor.  Examples:
     *     Landroid/os/Looper;.loop:()V
     *     Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V
     *
     * @param classAndMethodDesc the method to prepare
     *
     * @hide
     */
    public static final boolean cacheRegisterMap(String classAndMethodDesc) {
        return VMDebug.cacheRegisterMap(classAndMethodDesc);
    }

    /**
     * API for gathering and querying instruction counts.
     *
+60 −1
Original line number Diff line number Diff line
@@ -94,6 +94,25 @@ public class ZygoteInit {
    /** Controls whether we should preload resources during zygote init. */
    private static final boolean PRELOAD_RESOURCES = true;

    /**
     * List of methods we "warm up" in the register map cache.  These were
     * chosen because they appeared on the stack in GCs in multiple
     * applications.
     *
     * This is in a VM-ready format, to minimize string processing.  If a
     * class is not already loaded, or a method is not found, the entry
     * will be skipped.
     *
     * This doesn't really merit a separately-generated input file at this
     * time.  The list is fairly short, and the consequences of failure
     * are minor.
     */
    private static final String[] REGISTER_MAP_METHODS = {
        // (currently not doing any)
        //"Landroid/app/Activity;.setContentView:(I)V",
    };


    /**
     * Invokes a static "main(argv[]) method on class "className".
     * Converts various failing exceptions into RuntimeExceptions, with
@@ -318,6 +337,45 @@ public class ZygoteInit {
        }
    }

    /**
     * Pre-caches register maps for methods that are commonly used.
     */
    private static void cacheRegisterMaps() {
        String failed = null;
        int failure;
        long startTime = System.nanoTime();

        failure = 0;

        for (int i = 0; i < REGISTER_MAP_METHODS.length; i++) {
            String str = REGISTER_MAP_METHODS[i];

            if (!Debug.cacheRegisterMap(str)) {
                if (failed == null)
                    failed = str;
                failure++;
            }
        }

        long delta = System.nanoTime() - startTime;

        if (failure == REGISTER_MAP_METHODS.length) {
            if (REGISTER_MAP_METHODS.length > 0) {
                Log.i(TAG,
                    "Register map caching failed (precise GC not enabled?)");
            }
            return;
        }

        Log.i(TAG, "Register map cache: found " +
            (REGISTER_MAP_METHODS.length - failure) + " of " +
            REGISTER_MAP_METHODS.length + " methods in " +
            (delta / 1000000L) + "ms");
        if (failure > 0) {
            Log.i(TAG, "  First failure: " + failed);
        }
    }

    /**
     * Load in commonly used resources, so they can be shared across
     * processes.
@@ -510,6 +568,7 @@ public class ZygoteInit {
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preloadClasses();
            //cacheRegisterMaps();
            preloadResources();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());