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
This commit is contained in:
committed by
The Android Open Source Project
parent
43f3693035
commit
599c918d97
@@ -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.
|
||||
*
|
||||
|
||||
@@ -93,7 +93,26 @@ 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());
|
||||
|
||||
Reference in New Issue
Block a user