1 /* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 package com.sun.hotspot.igv.data.serialization; 25 26 import com.sun.hotspot.igv.data.GraphDocument; 27 import com.sun.hotspot.igv.data.Group; 28 import com.sun.hotspot.igv.data.InputBlock; 29 import com.sun.hotspot.igv.data.InputBytecode; 30 import com.sun.hotspot.igv.data.InputEdge; 31 import com.sun.hotspot.igv.data.InputGraph; 32 import com.sun.hotspot.igv.data.InputMethod; 33 import com.sun.hotspot.igv.data.InputNode; 34 import com.sun.hotspot.igv.data.Properties; 35 import com.sun.hotspot.igv.data.Property; 36 import java.io.IOException; 37 import java.io.Writer; 38 import java.util.HashSet; 39 import java.util.Set; 40 41 /** 42 * 43 * @author Thomas Wuerthinger 44 */ 45 public class Printer { 46 export(Writer writer, GraphDocument document)47 public void export(Writer writer, GraphDocument document) { 48 49 XMLWriter xmlWriter = new XMLWriter(writer); 50 51 try { 52 export(xmlWriter, document); 53 } catch (IOException ex) { 54 } 55 } 56 export(XMLWriter xmlWriter, GraphDocument document)57 private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException { 58 xmlWriter.startTag(Parser.ROOT_ELEMENT); 59 xmlWriter.writeProperties(document.getProperties()); 60 for (Group g : document.getGroups()) { 61 export(xmlWriter, g); 62 } 63 64 xmlWriter.endTag(); 65 xmlWriter.flush(); 66 } 67 export(XMLWriter writer, Group g)68 private void export(XMLWriter writer, Group g) throws IOException { 69 Properties attributes = new Properties(); 70 attributes.setProperty("difference", Boolean.toString(true)); 71 writer.startTag(Parser.GROUP_ELEMENT, attributes); 72 writer.writeProperties(g.getProperties()); 73 74 if (g.getMethod() != null) { 75 export(writer, g.getMethod()); 76 } 77 78 InputGraph previous = null; 79 for (InputGraph graph : g.getGraphs()) { 80 export(writer, graph, previous, true); 81 previous = graph; 82 } 83 84 writer.endTag(); 85 } 86 export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference)87 public void export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference) throws IOException { 88 89 writer.startTag(Parser.GRAPH_ELEMENT); 90 writer.writeProperties(graph.getProperties()); 91 writer.startTag(Parser.NODES_ELEMENT); 92 93 Set<InputNode> removed = new HashSet<InputNode>(); 94 Set<InputNode> equal = new HashSet<InputNode>(); 95 96 if (previous != null) { 97 for (InputNode n : previous.getNodes()) { 98 int id = n.getId(); 99 InputNode n2 = graph.getNode(id); 100 if (n2 == null) { 101 removed.add(n); 102 } else if (n.equals(n2)) { 103 equal.add(n); 104 } 105 } 106 } 107 108 if (difference) { 109 for (InputNode n : removed) { 110 writer.simpleTag(Parser.REMOVE_NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId()))); 111 } 112 } 113 114 for (InputNode n : graph.getNodes()) { 115 if (!difference || !equal.contains(n)) { 116 writer.startTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId()))); 117 writer.writeProperties(n.getProperties()); 118 writer.endTag(); 119 } 120 } 121 122 writer.endTag(); 123 124 writer.startTag(Parser.EDGES_ELEMENT); 125 Set<InputEdge> removedEdges = new HashSet<InputEdge>(); 126 Set<InputEdge> equalEdges = new HashSet<InputEdge>(); 127 128 if (previous != null) { 129 for (InputEdge e : previous.getEdges()) { 130 if (graph.getEdges().contains(e)) { 131 equalEdges.add(e); 132 } else { 133 removedEdges.add(e); 134 } 135 } 136 } 137 138 if (difference) { 139 for (InputEdge e : removedEdges) { 140 writer.simpleTag(Parser.REMOVE_EDGE_ELEMENT, createProperties(e)); 141 } 142 } 143 144 for (InputEdge e : graph.getEdges()) { 145 if (!difference || !equalEdges.contains(e)) { 146 if (!equalEdges.contains(e)) { 147 writer.simpleTag(Parser.EDGE_ELEMENT, createProperties(e)); 148 } 149 } 150 } 151 152 writer.endTag(); 153 154 writer.startTag(Parser.CONTROL_FLOW_ELEMENT); 155 for (InputBlock b : graph.getBlocks()) { 156 157 writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName())); 158 159 writer.startTag(Parser.SUCCESSORS_ELEMENT); 160 for (InputBlock s : b.getSuccessors()) { 161 writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName())); 162 } 163 writer.endTag(); 164 165 writer.startTag(Parser.NODES_ELEMENT); 166 for (InputNode n : b.getNodes()) { 167 writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + "")); 168 } 169 writer.endTag(); 170 171 writer.endTag(); 172 173 } 174 175 writer.endTag(); 176 writer.endTag(); 177 } 178 export(XMLWriter w, InputMethod method)179 private void export(XMLWriter w, InputMethod method) throws IOException { 180 181 w.startTag(Parser.METHOD_ELEMENT, new Properties(Parser.METHOD_BCI_PROPERTY, method.getBci() + "", Parser.METHOD_NAME_PROPERTY, method.getName(), Parser.METHOD_SHORT_NAME_PROPERTY, method.getShortName())); 182 183 w.writeProperties(method.getProperties()); 184 185 if (method.getInlined().size() > 0) { 186 w.startTag(Parser.INLINE_ELEMENT); 187 for (InputMethod m : method.getInlined()) { 188 export(w, m); 189 } 190 w.endTag(); 191 } 192 193 w.startTag(Parser.BYTECODES_ELEMENT); 194 195 StringBuilder b = new StringBuilder(); 196 b.append("<![CDATA[\n"); 197 for (InputBytecode code : method.getBytecodes()) { 198 b.append(code.getBci()); 199 b.append(" "); 200 b.append(code.getName()); 201 b.append("\n"); 202 203 } 204 b.append("]]>"); 205 w.write(b.toString()); 206 w.endTag(); 207 w.endTag(); 208 } 209 createProperties(InputEdge edge)210 private Properties createProperties(InputEdge edge) { 211 Properties p = new Properties(); 212 p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex())); 213 p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo())); 214 p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom())); 215 return p; 216 } 217 } 218