summaryrefslogtreecommitdiffstats
path: root/tools/preload
diff options
context:
space:
mode:
authorBob Lee <crazybob@google.com>2009-08-11 01:16:03 -0700
committerBob Lee <crazybob@google.com>2009-08-11 12:42:02 -0700
commit2e93f65cab0b4b21a1285b83e985559325e87a3a (patch)
treec6eccbbe77106632fb5d2ce9ffcfa740948dc6c8 /tools/preload
parent8af63bc97fb2d66e5fb1dab5bcf31ca044dced7b (diff)
downloadframeworks_base-2e93f65cab0b4b21a1285b83e985559325e87a3a.zip
frameworks_base-2e93f65cab0b4b21a1285b83e985559325e87a3a.tar.gz
frameworks_base-2e93f65cab0b4b21a1285b83e985559325e87a3a.tar.bz2
Updated preloaded-classes file.
Diffstat (limited to 'tools/preload')
-rw-r--r--tools/preload/20090811.compiledbin0 -> 15749051 bytes
-rw-r--r--tools/preload/ClassRank.java2
-rw-r--r--tools/preload/LoadedClass.java40
-rw-r--r--tools/preload/Policy.java56
-rw-r--r--tools/preload/PrintCsv.java33
-rw-r--r--tools/preload/Proc.java49
-rw-r--r--tools/preload/WritePreloadedClassFile.java94
-rw-r--r--tools/preload/preload.iml5
-rw-r--r--tools/preload/preload.ipr44
9 files changed, 147 insertions, 176 deletions
diff --git a/tools/preload/20090811.compiled b/tools/preload/20090811.compiled
new file mode 100644
index 0000000..dd61487
--- /dev/null
+++ b/tools/preload/20090811.compiled
Binary files differ
diff --git a/tools/preload/ClassRank.java b/tools/preload/ClassRank.java
index 3699b89..c562d5c 100644
--- a/tools/preload/ClassRank.java
+++ b/tools/preload/ClassRank.java
@@ -26,7 +26,7 @@ class ClassRank implements Comparator<Operation> {
* Increase this number to add more weight to classes which were loaded
* earlier.
*/
- static final int SEQUENCE_WEIGHT = 500; // 5 ms
+ static final int SEQUENCE_WEIGHT = 500; // 0.5ms
static final int BUCKET_SIZE = 5;
diff --git a/tools/preload/LoadedClass.java b/tools/preload/LoadedClass.java
index 5782807..9ef17f5 100644
--- a/tools/preload/LoadedClass.java
+++ b/tools/preload/LoadedClass.java
@@ -15,10 +15,7 @@
*/
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
/**
* A loaded class.
@@ -54,7 +51,7 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
}
void measureMemoryUsage() {
- this.memoryUsage = MemoryUsage.forClass(name);
+// this.memoryUsage = MemoryUsage.forClass(name);
}
int mlt = -1;
@@ -102,31 +99,20 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
}
}
- /**
- * Counts loads by apps.
- */
- int appLoads() {
- return operationsByApps(loads);
- }
-
- /**
- * Counts inits by apps.
- */
- int appInits() {
- return operationsByApps(initializations);
+ /** Returns names of apps that loaded this class. */
+ Set<String> applicationNames() {
+ Set<String> appNames = new HashSet<String>();
+ addProcessNames(loads, appNames);
+ addProcessNames(initializations, appNames);
+ return appNames;
}
- /**
- * Counts number of app operations in the given list.
- */
- private static int operationsByApps(List<Operation> operations) {
- int byApps = 0;
- for (Operation operation : operations) {
+ private void addProcessNames(List<Operation> ops, Set<String> appNames) {
+ for (Operation operation : ops) {
if (operation.process.isApplication()) {
- byApps++;
+ appNames.add(operation.process.name);
}
}
- return byApps;
}
public int compareTo(LoadedClass o) {
@@ -160,4 +146,8 @@ class LoadedClass implements Serializable, Comparable<LoadedClass> {
return false;
}
+
+ public boolean isPreloadable() {
+ return systemClass && Policy.isPreloadableClass(name);
+ }
}
diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java
index 554966b..ade889e3 100644
--- a/tools/preload/Policy.java
+++ b/tools/preload/Policy.java
@@ -24,47 +24,32 @@ import java.util.Set;
public class Policy {
/**
- * This location (in the build system) of the preloaded-classes file.
- */
- private static final String PRELOADED_CLASS_FILE = "frameworks/base/preloaded-classes";
-
- /**
- * The internal process name of the system process. Note, this also shows up as
- * "system_process", e.g. in ddms.
+ * No constructor - use static methods only
*/
- private static final String SYSTEM_SERVER_PROCESS_NAME = "system_server";
+ private Policy() {}
- /**
- * Names of non-application processes - these will not be checked for preloaded classes.
- *
- * TODO: Replace this hardcoded list with a walk up the parent chain looking for zygote.
+ /**
+ * This location (in the build system) of the preloaded-classes file.
*/
- private static final Set<String> NOT_FROM_ZYGOTE = new HashSet<String>(Arrays.asList(
- "zygote",
- "dexopt",
- "unknown",
- SYSTEM_SERVER_PROCESS_NAME,
- "com.android.development",
- "app_process" // am & other shell commands
- ));
+ private static final String PRELOADED_CLASS_FILE
+ = "frameworks/base/preloaded-classes";
- /**
- * Long running services. These are restricted in their contribution to the preloader
- * because their launch time is less critical.
+ /**
+ * Long running services. These are restricted in their contribution to the
+ * preloader because their launch time is less critical.
*/
private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
- SYSTEM_SERVER_PROCESS_NAME,
- "com.android.acore",
- // Commented out to make sure DefaultTimeZones gets preloaded.
- // "com.android.phone",
+ "system_server",
"com.google.process.content",
- "android.process.media"
+ "android.process.media",
+ "com.google.process.gapps"
));
/**
* Classes which we shouldn't load from the Zygote.
*/
- private static final Set<String> EXCLUDED_CLASSES = new HashSet<String>(Arrays.asList(
+ private static final Set<String> EXCLUDED_CLASSES
+ = new HashSet<String>(Arrays.asList(
// Binders
"android.app.AlarmManager",
"android.app.SearchManager",
@@ -75,15 +60,9 @@ public class Policy {
"android.os.AsyncTask",
"android.pim.ContactsAsyncHelper",
"java.lang.ProcessManager"
-
));
/**
- * No constructor - use static methods only
- */
- private Policy() {}
-
- /**
* Returns the path/file name of the preloaded classes file that will be written
* by WritePreloadedClassFile.
*/
@@ -92,13 +71,6 @@ public class Policy {
}
/**
- * Reports if a given process name was created from zygote
- */
- public static boolean isFromZygote(String processName) {
- return !NOT_FROM_ZYGOTE.contains(processName);
- }
-
- /**
* Reports if the given process name is a "long running" process or service
*/
public static boolean isService(String processName) {
diff --git a/tools/preload/PrintCsv.java b/tools/preload/PrintCsv.java
index 9f2a318..62f4271 100644
--- a/tools/preload/PrintCsv.java
+++ b/tools/preload/PrintCsv.java
@@ -18,6 +18,9 @@ import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.BufferedInputStream;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TreeSet;
/**
* Prints raw information in CSV format.
@@ -37,13 +40,14 @@ public class PrintCsv {
+ ",Preloaded"
+ ",Median Load Time (us)"
+ ",Median Init Time (us)"
+ + ",Process Names"
+ ",Load Count"
- + ",Init Count"
- + ",Managed Heap (B)"
- + ",Native Heap (B)"
- + ",Managed Pages (kB)"
- + ",Native Pages (kB)"
- + ",Other Pages (kB)");
+ + ",Init Count");
+// + ",Managed Heap (B)"
+// + ",Native Heap (B)"
+// + ",Managed Pages (kB)"
+// + ",Native Pages (kB)"
+// + ",Other Pages (kB)");
MemoryUsage baseline = root.baseline;
@@ -60,10 +64,23 @@ public class PrintCsv {
System.out.print(',');
System.out.print(loadedClass.medianInitTimeMicros());
System.out.print(',');
+ System.out.print('"');
+
+ Set<String> procNames = new TreeSet<String>();
+ for (Operation op : loadedClass.loads)
+ procNames.add(op.process.name);
+ for (Operation op : loadedClass.initializations)
+ procNames.add(op.process.name);
+ for (String name : procNames) {
+ System.out.print(name + "\n");
+ }
+
+ System.out.print('"');
+ System.out.print(',');
System.out.print(loadedClass.loads.size());
System.out.print(',');
System.out.print(loadedClass.initializations.size());
-
+/*
if (loadedClass.memoryUsage.isAvailable()) {
MemoryUsage subtracted
= loadedClass.memoryUsage.subtract(baseline);
@@ -82,7 +99,7 @@ public class PrintCsv {
} else {
System.out.print(",n/a,n/a,n/a,n/a,n/a");
}
-
+*/
System.out.println();
}
}
diff --git a/tools/preload/Proc.java b/tools/preload/Proc.java
index 22697f8..66e04dc 100644
--- a/tools/preload/Proc.java
+++ b/tools/preload/Proc.java
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-import java.util.Set;
-import java.util.HashSet;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
@@ -23,7 +21,6 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
-import java.util.TreeSet;
import java.io.Serializable;
/**
@@ -38,11 +35,6 @@ class Proc implements Serializable {
*/
static final int PERCENTAGE_TO_PRELOAD = 75;
- /**
- * Maximum number of classes to preload for a given process.
- */
- static final int MAX_TO_PRELOAD = 100;
-
/** Parent process. */
final Proc parent;
@@ -97,11 +89,9 @@ class Proc implements Serializable {
/**
* Returns a list of classes which should be preloaded.
- *
- * @param takeAllClasses forces all classes to be taken (irrespective of ranking)
*/
- List<LoadedClass> highestRankedClasses(boolean takeAllClasses) {
- if (!isApplication()) {
+ List<LoadedClass> highestRankedClasses() {
+ if (!isApplication() || Policy.isService(this.name)) {
return Collections.emptyList();
}
@@ -114,25 +104,13 @@ class Proc implements Serializable {
int timeToSave = totalTimeMicros() * percentageToPreload() / 100;
int timeSaved = 0;
- boolean service = Policy.isService(this.name);
-
+ int count = 0;
List<LoadedClass> highest = new ArrayList<LoadedClass>();
for (Operation operation : ranked) {
-
- // These are actual ranking decisions, which can be overridden
- if (!takeAllClasses) {
- if (highest.size() >= MAX_TO_PRELOAD) {
- System.out.println(name + " got "
- + (timeSaved * 100 / timeToSave) + "% through");
- break;
- }
-
- if (timeSaved >= timeToSave) {
- break;
- }
+ if (timeSaved >= timeToSave || count++ > 100) {
+ break;
}
- // The remaining rules apply even to wired-down processes
if (!Policy.isPreloadableClass(operation.loadedClass.name)) {
continue;
}
@@ -140,13 +118,8 @@ class Proc implements Serializable {
if (!operation.loadedClass.systemClass) {
continue;
}
-
- // Only load java.* class for services.
- if (!service || operation.loadedClass.name.startsWith("java.")) {
- highest.add(operation.loadedClass);
- }
-
- // For services, still count the time even if it's not in java.*
+
+ highest.add(operation.loadedClass);
timeSaved += operation.medianExclusiveTimeMicros();
}
@@ -166,11 +139,13 @@ class Proc implements Serializable {
/**
* Returns true if this process is an app.
- *
- * TODO: Replace the hardcoded list with a walk up the parent chain looking for zygote.
*/
public boolean isApplication() {
- return Policy.isFromZygote(name);
+ if (name.equals("com.android.development")) {
+ return false;
+ }
+
+ return parent != null && parent.name.equals("zygote");
}
/**
diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java
index d87b1f0..b209af0 100644
--- a/tools/preload/WritePreloadedClassFile.java
+++ b/tools/preload/WritePreloadedClassFile.java
@@ -20,8 +20,6 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -32,71 +30,85 @@ import java.util.TreeSet;
public class WritePreloadedClassFile {
public static void main(String[] args) throws IOException, ClassNotFoundException {
-
- // Process command-line arguments first
- List<String> wiredProcesses = new ArrayList<String>();
- String inputFileName = null;
- int argOffset = 0;
- try {
- while ("--preload-all-process".equals(args[argOffset])) {
- argOffset++;
- wiredProcesses.add(args[argOffset++]);
- }
-
- inputFileName = args[argOffset++];
- } catch (RuntimeException e) {
- System.err.println("Usage: WritePreloadedClassFile " +
- "[--preload-all-process process-name] " +
- "[compiled log file]");
- System.exit(0);
+ if (args.length != 1) {
+ System.err.println("Usage: WritePreloadedClassFile [compiled log]");
+ System.exit(-1);
}
+ String rootFile = args[0];
+ Root root = Root.fromFile(rootFile);
- Root root = Root.fromFile(inputFileName);
-
+ // No classes are preloaded to start.
for (LoadedClass loadedClass : root.loadedClasses.values()) {
loadedClass.preloaded = false;
}
+ // Open preloaded-classes file for output.
Writer out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(Policy.getPreloadedClassFileName()),
Charset.forName("US-ASCII")));
out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n");
out.write("# Automatically generated by /frameworks/base/tools/preload.\n");
- out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD + ", weight="
- + ClassRank.SEQUENCE_WEIGHT
+ out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD
+ + ", weight=" + ClassRank.SEQUENCE_WEIGHT
+ ", bucket_size=" + ClassRank.BUCKET_SIZE
+ "\n");
- for (String wiredProcess : wiredProcesses) {
- out.write("# forcing classes loaded by: " + wiredProcess + "\n");
- }
- Set<LoadedClass> highestRanked = new TreeSet<LoadedClass>();
- for (Proc proc : root.processes.values()) {
- // test to see if this is one of the wired-down ("take all classes") processes
- boolean isWired = wiredProcesses.contains(proc.name);
-
- List<LoadedClass> highestForProc = proc.highestRankedClasses(isWired);
+ Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();
+
+ // Preload all classes that were loaded by at least 2 apps, if both
+ // apps run at the same time, they'll share memory.
+ for (LoadedClass loadedClass : root.loadedClasses.values()) {
+ if (!loadedClass.isPreloadable()) {
+ continue;
+ }
- System.out.println(proc.name + ": " + highestForProc.size());
+ Set<String> appNames = loadedClass.applicationNames();
- for (LoadedClass loadedClass : highestForProc) {
- loadedClass.preloaded = true;
+ if (appNames.size() > 3) {
+ toPreload.add(loadedClass);
}
- highestRanked.addAll(highestForProc);
}
- for (LoadedClass loadedClass : highestRanked) {
+ // Try to make individual apps start faster by preloading slowest
+ // classes.
+ for (Proc proc : root.processes.values()) {
+ toPreload.addAll(proc.highestRankedClasses());
+ }
+
+ System.out.println(toPreload.size() + " classes will be preloaded.");
+
+ // Make classes that were already loaded by the zygote explicit.
+ // This adds minimal overhead but avoid confusion about classes not
+ // appearing in the list.
+ addAllClassesFor("zygote", root, toPreload);
+
+ for (LoadedClass loadedClass : toPreload) {
out.write(loadedClass.name);
out.write('\n');
}
out.close();
- System.out.println(highestRanked.size()
- + " classes will be preloaded.");
-
// Update data to reflect LoadedClass.preloaded changes.
- root.toFile(inputFileName);
+ for (LoadedClass loadedClass : toPreload) {
+ loadedClass.preloaded = true;
+ }
+ root.toFile(rootFile);
+ }
+
+ private static void addAllClassesFor(String packageName, Root root,
+ Set<LoadedClass> toPreload) {
+ for (Proc proc : root.processes.values()) {
+ if (proc.name.equals(packageName)) {
+ for (Operation operation : proc.operations) {
+ // TODO: I'm not sure how the zygote loaded classes that
+ // aren't supposed to be preloadable...
+ if (operation.loadedClass.isPreloadable()) {
+ toPreload.add(operation.loadedClass);
+ }
+ }
+ }
+ }
}
}
diff --git a/tools/preload/preload.iml b/tools/preload/preload.iml
index d1fab57..2d87c55 100644
--- a/tools/preload/preload.iml
+++ b/tools/preload/preload.iml
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
- <output url="file:///tmp/preload/" />
+ <output url="file:///tmp/preload" />
+ <output-test url="file:///tmp/preload" />
<exclude-output />
- <output-test url="file:///tmp/preload/" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntryProperties />
</component>
</module>
diff --git a/tools/preload/preload.ipr b/tools/preload/preload.ipr
index c5613ad..f78bf76 100644
--- a/tools/preload/preload.ipr
+++ b/tools/preload/preload.ipr
@@ -114,6 +114,7 @@
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
<option name="MAXIMUM_HEAP_SIZE" value="128" />
</component>
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
@@ -125,13 +126,13 @@
<component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" />
<component name="InspectionProjectProfileManager">
<option name="PROJECT_PROFILE" value="Project Default" />
- <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
- <scopes />
+ <option name="USE_PROJECT_PROFILE" value="true" />
+ <version value="1.0" />
<profiles>
<profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" />
<option name="myLocal" value="false" />
- <inspection_tool class="JavaDoc" level="WARNING" enabled="false">
+ <inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
@@ -160,14 +161,19 @@
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="myAdditionalJavadocTags" value="" />
</inspection_tool>
- <inspection_tool class="OnDemandImport" level="WARNING" enabled="true" />
- <inspection_tool class="SamePackageImport" level="WARNING" enabled="true" />
- <inspection_tool class="JavaLangImport" level="WARNING" enabled="true" />
- <inspection_tool class="RedundantImport" level="WARNING" enabled="true" />
- <inspection_tool class="UnusedImport" level="WARNING" enabled="true" />
+ <inspection_tool class="JavaLangImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="OnDemandImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SamePackageImport" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnusedImport" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</profiles>
- <list size="0" />
+ <list size="4">
+ <item index="0" class="java.lang.String" itemvalue="WARNING" />
+ <item index="1" class="java.lang.String" itemvalue="SERVER PROBLEM" />
+ <item index="2" class="java.lang.String" itemvalue="INFO" />
+ <item index="3" class="java.lang.String" itemvalue="ERROR" />
+ </list>
</component>
<component name="JavacSettings">
<option name="DEBUGGING_INFO" value="true" />
@@ -332,13 +338,19 @@
<option name="USE_CLIENT_FILTER" value="true" />
<option name="CLIENT" value="" />
</component>
+ <component name="ProjectDetails">
+ <option name="projectName" value="preload" />
+ </component>
<component name="ProjectFileVersion" converted="true" />
+ <component name="ProjectKey">
+ <option name="state" value="project:///Volumes/Android/donut/frameworks/base/tools/preload/preload.ipr" />
+ </component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/preload.iml" filepath="$PROJECT_DIR$/preload.iml" />
</modules>
</component>
- <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
<output url="file:///tmp/preload" />
</component>
<component name="RmicSettings">
@@ -374,6 +386,9 @@
<option name="myValidatorValidationEnabled" value="true" />
<option name="myReportErrorsAsWarnings" value="true" />
</component>
+ <component name="SvnBranchConfigurationManager">
+ <option name="mySupportsUserInfoFilter" value="true" />
+ </component>
<component name="SvnChangesBrowserSettings">
<option name="USE_AUTHOR_FIELD" value="true" />
<option name="AUTHOR" value="" />
@@ -381,15 +396,6 @@
<option name="USE_PROJECT_SETTINGS" value="true" />
<option name="USE_ALTERNATE_LOCATION" value="false" />
</component>
- <component name="SvnConfiguration">
- <option name="USER" value="" />
- <option name="PASSWORD" value="" />
- <option name="PROCESS_UNRESOLVED" value="false" />
- <option name="LAST_MERGED_REVISION" />
- <option name="UPDATE_RUN_STATUS" value="false" />
- <option name="UPDATE_RECURSIVELY" value="true" />
- <option name="MERGE_DRY_RUN" value="false" />
- </component>
<component name="VCS.FileViewConfiguration">
<option name="SELECTED_STATUSES" value="DEFAULT" />
<option name="SELECTED_COLUMNS" value="DEFAULT" />