2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 import java.io.IOException;
18 import java.io.FileReader;
19 import java.io.BufferedReader;
20 import java.io.PrintStream;
22 import java.util.TreeSet;
23 import java.util.HashSet;
24 import java.util.Iterator;
27 * Prints HTML containing removed and added files.
29 public class PrintHtmlDiff {
31 private static final String OLD_PRELOADED_CLASSES
32 = "old-preloaded-classes";
34 public static void main(String[] args) throws IOException,
35 ClassNotFoundException {
36 Root root = Root.fromFile(args[0]);
38 BufferedReader oldClasses = new BufferedReader(
39 new FileReader(OLD_PRELOADED_CLASSES));
41 // Classes loaded implicitly by the zygote.
42 Set<LoadedClass> zygote = new HashSet<LoadedClass>();
43 for (Proc proc : root.processes.values()) {
44 if (proc.name.equals("zygote")) {
45 for (Operation op : proc.operations) {
46 zygote.add(op.loadedClass);
52 Set<LoadedClass> removed = new TreeSet<LoadedClass>();
53 Set<LoadedClass> added = new TreeSet<LoadedClass>();
55 for (LoadedClass loadedClass : root.loadedClasses.values()) {
56 if (loadedClass.preloaded && !zygote.contains(loadedClass)) {
57 added.add(loadedClass);
62 while ((line = oldClasses.readLine()) != null) {
64 LoadedClass clazz = root.loadedClasses.get(line);
67 if (!clazz.preloaded) removed.add(clazz);
71 PrintStream out = System.out;
73 out.println("<html><body>");
74 out.println("<style>");
75 out.println("a, th, td, h2 { font-family: arial }");
76 out.println("th, td { font-size: small }");
77 out.println("</style>");
78 out.println("<script src=\"sorttable.js\"></script>");
79 out.println("<p><a href=\"#removed\">Removed</a>");
80 out.println("<a name=\"added\"/><h2>Added</h2>");
81 printTable(out, root.baseline, added);
82 out.println("<a name=\"removed\"/><h2>Removed</h2>");
83 printTable(out, root.baseline, removed);
84 out.println("</body></html>");
87 static void printTable(PrintStream out, MemoryUsage baseline,
88 Iterable<LoadedClass> classes) {
89 out.println("<table border=\"1\" cellpadding=\"5\""
90 + " class=\"sortable\">");
92 out.println("<thead><tr>");
93 out.println("<th>Name</th>");
94 out.println("<th>Load Time (us)</th>");
95 out.println("<th>Loaded By</th>");
96 out.println("<th>Heap (B)</th>");
97 out.println("<th>Pages</th>");
98 out.println("</tr></thead>");
100 for (LoadedClass clazz : classes) {
102 out.println("<td>" + clazz.name + "</td>");
103 out.println("<td>" + clazz.medianTimeMicros() + "</td>");
106 Set<String> procNames = new TreeSet<String>();
107 for (Operation op : clazz.loads) procNames.add(op.process.name);
108 for (Operation op : clazz.initializations) {
109 procNames.add(op.process.name);
111 if (procNames.size() <= 3) {
112 for (String name : procNames) {
113 out.print(name + "<br/>");
116 Iterator<String> i = procNames.iterator();
117 out.print(i.next() + "<br/>");
118 out.print(i.next() + "<br/>");
119 out.print("...and " + (procNames.size() - 2)
122 out.println("</td>");
124 if (clazz.memoryUsage.isAvailable()) {
125 MemoryUsage subtracted
126 = clazz.memoryUsage.subtract(baseline);
128 out.println("<td>" + (subtracted.javaHeapSize()
129 + subtracted.nativeHeapSize) + "</td>");
130 out.println("<td>" + subtracted.totalPages() + "</td>");
132 for (int i = 0; i < 2; i++) {
133 out.println("<td>n/a</td>");
137 out.println("</tr>");
140 out.println("</table>");