diff options
author | Bob Lee <crazybob@google.com> | 2009-08-11 01:16:03 -0700 |
---|---|---|
committer | Bob Lee <crazybob@google.com> | 2009-08-11 12:42:02 -0700 |
commit | 2e93f65cab0b4b21a1285b83e985559325e87a3a (patch) | |
tree | c6eccbbe77106632fb5d2ce9ffcfa740948dc6c8 /tools/preload | |
parent | 8af63bc97fb2d66e5fb1dab5bcf31ca044dced7b (diff) | |
download | frameworks_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.compiled | bin | 0 -> 15749051 bytes | |||
-rw-r--r-- | tools/preload/ClassRank.java | 2 | ||||
-rw-r--r-- | tools/preload/LoadedClass.java | 40 | ||||
-rw-r--r-- | tools/preload/Policy.java | 56 | ||||
-rw-r--r-- | tools/preload/PrintCsv.java | 33 | ||||
-rw-r--r-- | tools/preload/Proc.java | 49 | ||||
-rw-r--r-- | tools/preload/WritePreloadedClassFile.java | 94 | ||||
-rw-r--r-- | tools/preload/preload.iml | 5 | ||||
-rw-r--r-- | tools/preload/preload.ipr | 44 |
9 files changed, 147 insertions, 176 deletions
diff --git a/tools/preload/20090811.compiled b/tools/preload/20090811.compiled Binary files differnew file mode 100644 index 0000000..dd61487 --- /dev/null +++ b/tools/preload/20090811.compiled 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" /> |