19d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/* 29d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * Copyright (C) 2009 The Android Open Source Project 39d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * 49d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * Licensed under the Apache License, Version 2.0 (the "License"); 59d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * you may not use this file except in compliance with the License. 69d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * You may obtain a copy of the License at 79d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * 89d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * http://www.apache.org/licenses/LICENSE-2.0 99d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * 109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * Unless required by applicable law or agreed to in writing, software 119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * distributed under the License is distributed on an "AS IS" BASIS, 129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * See the License for the specific language governing permissions and 149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * limitations under the License. 159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee */ 169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 179d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.io.IOException; 189d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.io.FileReader; 199d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.io.BufferedReader; 209d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.io.PrintStream; 219d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.util.Set; 229d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.util.TreeSet; 239d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.util.HashSet; 249d2d6e14b0932b6a74e01f393d5efed61458941bBob Leeimport java.util.Iterator; 259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee/** 279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee * Prints HTML containing removed and added files. 289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee */ 299d2d6e14b0932b6a74e01f393d5efed61458941bBob Leepublic class PrintHtmlDiff { 309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee private static final String OLD_PRELOADED_CLASSES 329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee = "old-preloaded-classes"; 339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee public static void main(String[] args) throws IOException, 359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee ClassNotFoundException { 369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Root root = Root.fromFile(args[0]); 379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee BufferedReader oldClasses = new BufferedReader( 399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee new FileReader(OLD_PRELOADED_CLASSES)); 409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // Classes loaded implicitly by the zygote. 429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<LoadedClass> zygote = new HashSet<LoadedClass>(); 439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (Proc proc : root.processes.values()) { 449d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (proc.name.equals("zygote")) { 459d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (Operation op : proc.operations) { 469d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee zygote.add(op.loadedClass); 479d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 489d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee break; 499d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 509d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 519d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 529d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<LoadedClass> removed = new TreeSet<LoadedClass>(); 539d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<LoadedClass> added = new TreeSet<LoadedClass>(); 549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 559d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (LoadedClass loadedClass : root.loadedClasses.values()) { 569d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (loadedClass.preloaded && !zygote.contains(loadedClass)) { 579d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee added.add(loadedClass); 589d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 599d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 609d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 619d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee String line; 629d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee while ((line = oldClasses.readLine()) != null) { 639d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee line = line.trim(); 649d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee LoadedClass clazz = root.loadedClasses.get(line); 659d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (clazz != null) { 669d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee added.remove(clazz); 679d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (!clazz.preloaded) removed.add(clazz); 689d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 699d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 709d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 719d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee PrintStream out = System.out; 729d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 739d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<html><body>"); 749d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<style>"); 759d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("a, th, td, h2 { font-family: arial }"); 769d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("th, td { font-size: small }"); 779d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</style>"); 789d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<script src=\"sorttable.js\"></script>"); 799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<p><a href=\"#removed\">Removed</a>"); 809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<a name=\"added\"/><h2>Added</h2>"); 819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee printTable(out, root.baseline, added); 829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<a name=\"removed\"/><h2>Removed</h2>"); 839d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee printTable(out, root.baseline, removed); 849d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</body></html>"); 859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee static void printTable(PrintStream out, MemoryUsage baseline, 889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Iterable<LoadedClass> classes) { 899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<table border=\"1\" cellpadding=\"5\"" 909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee + " class=\"sortable\">"); 919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<thead><tr>"); 939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<th>Name</th>"); 949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<th>Load Time (us)</th>"); 959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<th>Loaded By</th>"); 969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<th>Heap (B)</th>"); 979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<th>Pages</th>"); 989d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</tr></thead>"); 999d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1009d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (LoadedClass clazz : classes) { 1019d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<tr>"); 1029d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>" + clazz.name + "</td>"); 1039d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>" + clazz.medianTimeMicros() + "</td>"); 1049d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1059d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>"); 1069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<String> procNames = new TreeSet<String>(); 1079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (Operation op : clazz.loads) procNames.add(op.process.name); 1089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (Operation op : clazz.initializations) { 1099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee procNames.add(op.process.name); 1109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (procNames.size() <= 3) { 1129d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (String name : procNames) { 1139d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.print(name + "<br/>"); 1149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1159d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 1169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Iterator<String> i = procNames.iterator(); 1179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.print(i.next() + "<br/>"); 1189d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.print(i.next() + "<br/>"); 1199d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.print("...and " + (procNames.size() - 2) 1209d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee + " others."); 1219d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1229d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</td>"); 1239d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1249d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (clazz.memoryUsage.isAvailable()) { 1259d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee MemoryUsage subtracted 1269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee = clazz.memoryUsage.subtract(baseline); 1279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>" + (subtracted.javaHeapSize() 1299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee + subtracted.nativeHeapSize) + "</td>"); 1309d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>" + subtracted.totalPages() + "</td>"); 1319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } else { 1329d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (int i = 0; i < 2; i++) { 1339d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("<td>n/a</td>"); 1349d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1369d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1379d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</tr>"); 1389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee out.println("</table>"); 1419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee} 143