| /* |
| * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| * |
| */ |
| package com.sun.hotspot.igv.data.serialization; |
| |
| import com.sun.hotspot.igv.data.GraphDocument; |
| import com.sun.hotspot.igv.data.Group; |
| import com.sun.hotspot.igv.data.InputBlock; |
| import com.sun.hotspot.igv.data.InputBytecode; |
| import com.sun.hotspot.igv.data.InputEdge; |
| import com.sun.hotspot.igv.data.InputGraph; |
| import com.sun.hotspot.igv.data.InputMethod; |
| import com.sun.hotspot.igv.data.InputNode; |
| import com.sun.hotspot.igv.data.Properties; |
| import com.sun.hotspot.igv.data.Property; |
| import java.io.IOException; |
| import java.io.Writer; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * |
| * @author Thomas Wuerthinger |
| */ |
| public class Printer { |
| |
| public void export(Writer writer, GraphDocument document) { |
| |
| XMLWriter xmlWriter = new XMLWriter(writer); |
| |
| try { |
| export(xmlWriter, document); |
| } catch (IOException ex) { |
| } |
| } |
| |
| private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException { |
| xmlWriter.startTag(Parser.ROOT_ELEMENT); |
| xmlWriter.writeProperties(document.getProperties()); |
| for (Group g : document.getGroups()) { |
| export(xmlWriter, g); |
| } |
| |
| xmlWriter.endTag(); |
| xmlWriter.flush(); |
| } |
| |
| private void export(XMLWriter writer, Group g) throws IOException { |
| Properties attributes = new Properties(); |
| attributes.setProperty("difference", Boolean.toString(true)); |
| writer.startTag(Parser.GROUP_ELEMENT, attributes); |
| writer.writeProperties(g.getProperties()); |
| |
| if (g.getMethod() != null) { |
| export(writer, g.getMethod()); |
| } |
| |
| InputGraph previous = null; |
| for (InputGraph graph : g.getGraphs()) { |
| export(writer, graph, previous, true); |
| previous = graph; |
| } |
| |
| writer.endTag(); |
| } |
| |
| public void export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference) throws IOException { |
| |
| writer.startTag(Parser.GRAPH_ELEMENT); |
| writer.writeProperties(graph.getProperties()); |
| writer.startTag(Parser.NODES_ELEMENT); |
| |
| Set<InputNode> removed = new HashSet<InputNode>(); |
| Set<InputNode> equal = new HashSet<InputNode>(); |
| |
| if (previous != null) { |
| for (InputNode n : previous.getNodes()) { |
| int id = n.getId(); |
| InputNode n2 = graph.getNode(id); |
| if (n2 == null) { |
| removed.add(n); |
| } else if (n.equals(n2)) { |
| equal.add(n); |
| } |
| } |
| } |
| |
| if (difference) { |
| for (InputNode n : removed) { |
| writer.simpleTag(Parser.REMOVE_NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId()))); |
| } |
| } |
| |
| for (InputNode n : graph.getNodes()) { |
| if (!difference || !equal.contains(n)) { |
| writer.startTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId()))); |
| writer.writeProperties(n.getProperties()); |
| writer.endTag(); |
| } |
| } |
| |
| writer.endTag(); |
| |
| writer.startTag(Parser.EDGES_ELEMENT); |
| Set<InputEdge> removedEdges = new HashSet<InputEdge>(); |
| Set<InputEdge> equalEdges = new HashSet<InputEdge>(); |
| |
| if (previous != null) { |
| for (InputEdge e : previous.getEdges()) { |
| if (graph.getEdges().contains(e)) { |
| equalEdges.add(e); |
| } else { |
| removedEdges.add(e); |
| } |
| } |
| } |
| |
| if (difference) { |
| for (InputEdge e : removedEdges) { |
| writer.simpleTag(Parser.REMOVE_EDGE_ELEMENT, createProperties(e)); |
| } |
| } |
| |
| for (InputEdge e : graph.getEdges()) { |
| if (!difference || !equalEdges.contains(e)) { |
| if (!equalEdges.contains(e)) { |
| writer.simpleTag(Parser.EDGE_ELEMENT, createProperties(e)); |
| } |
| } |
| } |
| |
| writer.endTag(); |
| |
| writer.startTag(Parser.CONTROL_FLOW_ELEMENT); |
| for (InputBlock b : graph.getBlocks()) { |
| |
| writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName())); |
| |
| writer.startTag(Parser.SUCCESSORS_ELEMENT); |
| for (InputBlock s : b.getSuccessors()) { |
| writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName())); |
| } |
| writer.endTag(); |
| |
| writer.startTag(Parser.NODES_ELEMENT); |
| for (InputNode n : b.getNodes()) { |
| writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + "")); |
| } |
| writer.endTag(); |
| |
| writer.endTag(); |
| |
| } |
| |
| writer.endTag(); |
| writer.endTag(); |
| } |
| |
| private void export(XMLWriter w, InputMethod method) throws IOException { |
| |
| 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())); |
| |
| w.writeProperties(method.getProperties()); |
| |
| if (method.getInlined().size() > 0) { |
| w.startTag(Parser.INLINE_ELEMENT); |
| for (InputMethod m : method.getInlined()) { |
| export(w, m); |
| } |
| w.endTag(); |
| } |
| |
| w.startTag(Parser.BYTECODES_ELEMENT); |
| |
| StringBuilder b = new StringBuilder(); |
| b.append("<![CDATA[\n"); |
| for (InputBytecode code : method.getBytecodes()) { |
| b.append(code.getBci()); |
| b.append(" "); |
| b.append(code.getName()); |
| b.append("\n"); |
| |
| } |
| b.append("]]>"); |
| w.write(b.toString()); |
| w.endTag(); |
| w.endTag(); |
| } |
| |
| private Properties createProperties(InputEdge edge) { |
| Properties p = new Properties(); |
| p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex())); |
| p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo())); |
| p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom())); |
| return p; |
| } |
| } |