blob: 14d17d66a52d2e6c64781a1553ad6e752dc5a305 [file] [log] [blame]
/*
* 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;
}
}