Updated preloaded-classes file.
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.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 @@
 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>();
 
-            System.out.println(proc.name + ": " + highestForProc.size());
-
-            for (LoadedClass loadedClass : highestForProc) {
-                loadedClass.preloaded = true;
+        // 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;
             }
-            highestRanked.addAll(highestForProc);
+
+            Set<String> appNames = loadedClass.applicationNames();
+
+            if (appNames.size() > 3) {
+                toPreload.add(loadedClass);
+            }
         }
 
-        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);
+                    }
+                }
+            }
+        }
     }
 }