blob: b101c85185c0659df54f7bb3e863a2d72dbb06c5 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17import java.io.IOException;
18import java.io.FileReader;
19import java.io.BufferedReader;
20import java.io.PrintStream;
21import java.util.Set;
22import java.util.TreeSet;
23import java.util.HashSet;
24import java.util.Iterator;
25
26/**
27 * Prints HTML containing removed and added files.
28 */
29public class PrintHtmlDiff {
30
31 private static final String OLD_PRELOADED_CLASSES
32 = "old-preloaded-classes";
33
34 public static void main(String[] args) throws IOException,
35 ClassNotFoundException {
36 Root root = Root.fromFile(args[0]);
37
38 BufferedReader oldClasses = new BufferedReader(
39 new FileReader(OLD_PRELOADED_CLASSES));
40
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);
47 }
48 break;
49 }
50 }
51
52 Set<LoadedClass> removed = new TreeSet<LoadedClass>();
53 Set<LoadedClass> added = new TreeSet<LoadedClass>();
54
55 for (LoadedClass loadedClass : root.loadedClasses.values()) {
56 if (loadedClass.preloaded && !zygote.contains(loadedClass)) {
57 added.add(loadedClass);
58 }
59 }
60
61 String line;
62 while ((line = oldClasses.readLine()) != null) {
63 line = line.trim();
64 LoadedClass clazz = root.loadedClasses.get(line);
65 if (clazz != null) {
66 added.remove(clazz);
67 if (!clazz.preloaded) removed.add(clazz);
68 }
69 }
70
71 PrintStream out = System.out;
72
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>");
85 }
86
87 static void printTable(PrintStream out, MemoryUsage baseline,
88 Iterable<LoadedClass> classes) {
89 out.println("<table border=\"1\" cellpadding=\"5\""
90 + " class=\"sortable\">");
91
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>");
99
100 for (LoadedClass clazz : classes) {
101 out.println("<tr>");
102 out.println("<td>" + clazz.name + "</td>");
103 out.println("<td>" + clazz.medianTimeMicros() + "</td>");
104
105 out.println("<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);
110 }
111 if (procNames.size() <= 3) {
112 for (String name : procNames) {
113 out.print(name + "<br/>");
114 }
115 } else {
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)
120 + " others.");
121 }
122 out.println("</td>");
123
124 if (clazz.memoryUsage.isAvailable()) {
125 MemoryUsage subtracted
126 = clazz.memoryUsage.subtract(baseline);
127
128 out.println("<td>" + (subtracted.javaHeapSize()
129 + subtracted.nativeHeapSize) + "</td>");
130 out.println("<td>" + subtracted.totalPages() + "</td>");
131 } else {
132 for (int i = 0; i < 2; i++) {
133 out.println("<td>n/a</td>");
134 }
135 }
136
137 out.println("</tr>");
138 }
139
140 out.println("</table>");
141 }
142}