Zygote: Add support for explicit preloading of resources.
Add a --preload-default command that instructs the zygote to preload resources. The command is a no-op if resources have already been preloaded. Test: manual. Change-Id: I4a846a7d911fa929af472d9071ffbff6df424176
This commit is contained in:
@@ -506,4 +506,24 @@ public class ZygoteProcess {
|
||||
state.writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the zygote to preload the default set of classes and resources. Returns
|
||||
* {@code true} if a preload was performed as a result of this call, and {@code false}
|
||||
* otherwise. The latter usually means that the zygote eagerly preloaded at startup
|
||||
* or due to a previous call to {@code preloadDefault}. Note that this call is synchronous.
|
||||
*/
|
||||
public boolean preloadDefault(String abi) throws ZygoteStartFailedEx, IOException {
|
||||
synchronized (mLock) {
|
||||
ZygoteState state = openZygoteSocketIfNeeded(abi);
|
||||
// Each query starts with the argument count (1 in this case)
|
||||
state.writer.write("1");
|
||||
state.writer.newLine();
|
||||
state.writer.write("--preload-default");
|
||||
state.writer.newLine();
|
||||
state.writer.flush();
|
||||
|
||||
return (state.inputStream.readInt() == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,15 @@ class WebViewZygoteInit {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void maybePreload() {
|
||||
// Do nothing, we don't need to call ZygoteInit.maybePreload() for the WebView zygote.
|
||||
protected void preload() {
|
||||
// Nothing to preload by default.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPreloadComplete() {
|
||||
// Webview zygotes don't preload any classes or resources or defaults, all of their
|
||||
// preloading is package specific.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -171,7 +171,9 @@ class ZygoteConnection {
|
||||
return handleAbiListQuery();
|
||||
}
|
||||
|
||||
maybePreload();
|
||||
if (parsedArgs.preloadDefault) {
|
||||
return handlePreload();
|
||||
}
|
||||
|
||||
if (parsedArgs.preloadPackage != null) {
|
||||
return handlePreloadPackage(parsedArgs.preloadPackage,
|
||||
@@ -282,8 +284,34 @@ class ZygoteConnection {
|
||||
}
|
||||
}
|
||||
|
||||
protected void maybePreload() {
|
||||
ZygoteInit.maybePreload();
|
||||
/**
|
||||
* Preloads resources if the zygote is in lazily preload mode. Writes the result of the
|
||||
* preload operation; {@code 0} when a preload was initiated due to this request and {@code 1}
|
||||
* if no preload was initiated. The latter implies that the zygote is not configured to load
|
||||
* resources lazy or that the zygote has already handled a previous request to handlePreload.
|
||||
*/
|
||||
private boolean handlePreload() {
|
||||
try {
|
||||
if (isPreloadComplete()) {
|
||||
mSocketOutStream.writeInt(1);
|
||||
} else {
|
||||
preload();
|
||||
mSocketOutStream.writeInt(0);
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Error writing to command socket", ioe);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void preload() {
|
||||
ZygoteInit.lazyPreload();
|
||||
}
|
||||
|
||||
protected boolean isPreloadComplete() {
|
||||
return ZygoteInit.isPreloadComplete();
|
||||
}
|
||||
|
||||
protected boolean handlePreloadPackage(String packagePath, String libsPath) {
|
||||
@@ -401,6 +429,13 @@ class ZygoteConnection {
|
||||
String preloadPackage;
|
||||
String preloadPackageLibs;
|
||||
|
||||
/**
|
||||
* Whether this is a request to start preloading the default resources and classes.
|
||||
* This argument only makes sense when the zygote is in lazy preload mode (i.e, when
|
||||
* it's started with --enable-lazy-preload).
|
||||
*/
|
||||
boolean preloadDefault;
|
||||
|
||||
/**
|
||||
* Constructs instance and parses args
|
||||
* @param args zygote command-line args
|
||||
@@ -564,6 +599,8 @@ class ZygoteConnection {
|
||||
} else if (arg.equals("--preload-package")) {
|
||||
preloadPackage = args[++curArg];
|
||||
preloadPackageLibs = args[++curArg];
|
||||
} else if (arg.equals("--preload-default")) {
|
||||
preloadDefault = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -578,7 +615,7 @@ class ZygoteConnection {
|
||||
throw new IllegalArgumentException(
|
||||
"Unexpected arguments after --preload-package.");
|
||||
}
|
||||
} else {
|
||||
} else if (!preloadDefault) {
|
||||
if (!seenRuntimeArgs) {
|
||||
throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
import dalvik.system.DexFile;
|
||||
import dalvik.system.PathClassLoader;
|
||||
import dalvik.system.VMRuntime;
|
||||
@@ -146,11 +147,11 @@ public class ZygoteInit {
|
||||
sPreloadComplete = true;
|
||||
}
|
||||
|
||||
public static void maybePreload() {
|
||||
if (!sPreloadComplete) {
|
||||
Log.i(TAG, "Lazily preloading resources.");
|
||||
preload(new BootTimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
|
||||
}
|
||||
public static void lazyPreload() {
|
||||
Preconditions.checkState(!sPreloadComplete);
|
||||
Log.i(TAG, "Lazily preloading resources.");
|
||||
|
||||
preload(new BootTimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
|
||||
}
|
||||
|
||||
private static void beginIcuCachePinning() {
|
||||
@@ -785,6 +786,10 @@ public class ZygoteInit {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isPreloadComplete() {
|
||||
return sPreloadComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class not instantiable.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user