1 /* 2 * Copyright (c) 2011, 2017, 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 package org.graalvm.graphio; 24 25 import java.io.Closeable; 26 import java.io.IOException; 27 import java.nio.channels.WritableByteChannel; 28 import java.util.Map; 29 30 /** 31 * Instance of output to dump informations about a compiler compilations. 32 * 33 * @param <G> the type of graph this instance handles 34 * @param <M> the type of methods this instance handles 35 */ 36 public final class GraphOutput<G, M> implements Closeable { 37 private final GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> printer; 38 39 private GraphOutput(GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?> p) { 40 this.printer = p; 41 } 42 43 /** 44 * Creates new builder to configure a future instance of {@link GraphOutput}. 45 * 46 * @param <G> the type of the graph 47 * @param <N> the type of the nodes 48 * @param <C> the type of the node classes 49 * @param <P> the type of the ports 50 * 51 * @param structure description of the structure of the graph 52 * @return the builder to configure 53 */ 54 public static <G, N, C, P> Builder<G, N, ?> newBuilder(GraphStructure<G, N, C, P> structure) { 55 return new Builder<>(structure); 56 } 57 58 /** 59 * Begins a compilation group. 60 * 61 * @param forGraph 62 * @param name 63 * @param shortName 64 * @param method 65 * @param bci 66 * @param properties 67 * @throws IOException 68 */ 69 public void beginGroup(G forGraph, String name, String shortName, M method, int bci, Map<? extends Object, ? extends Object> properties) throws IOException { 70 printer.beginGroup(forGraph, name, shortName, method, bci, properties); 71 } 72 73 /** 74 * Prints a single graph. 75 * 76 * @param graph 77 * @param properties 78 * @param id 79 * @param format 80 * @param args 81 * @throws IOException 82 */ 83 public void print(G graph, Map<? extends Object, ? extends Object> properties, int id, String format, Object... args) throws IOException { 84 printer.print(graph, properties, id, format, args); 85 } 86 87 /** 88 * Ends compilation group. 89 * 90 * @throws IOException 91 */ 92 public void endGroup() throws IOException { 93 printer.endGroup(); 94 } 95 96 /** 97 * Closes the output. Closes allocated resources and associated output channel. 98 */ 99 @Override 100 public void close() { 101 printer.close(); 102 } 103 104 /** 105 * Builder to configure and create an instance of {@link GraphOutput}. 106 * 107 * @param <G> the type of the (root element of) graph 108 * @param <N> the type of the nodes 109 * @param <M> the type of the methods 110 */ 111 public static final class Builder<G, N, M> { 112 private final GraphStructure<G, N, ?, ?> structure; 113 private GraphElements<M, ?, ?, ?> elements = null; 114 private GraphTypes types = DefaultGraphTypes.DEFAULT; 115 private GraphBlocks<G, ?, N> blocks = DefaultGraphBlocks.empty(); 116 private int major = 4; 117 private int minor = 0; 118 119 Builder(GraphStructure<G, N, ?, ?> structure) { 120 this.structure = structure; 121 } 122 123 /** 124 * Chooses which version of the protocol to use. The default version is <code>4.0</code> 125 * (when the {@link GraphOutput} & co. classes were introduced). The default can be changed 126 * to other known versions manually by calling this method. 127 * 128 * @param majorVersion by default 4, newer version may be known 129 * @param minorVersion usually 0 130 * @return this builder 131 * @since 0.28 132 */ 133 public Builder<G, N, M> protocolVersion(int majorVersion, int minorVersion) { 134 this.major = majorVersion; 135 this.minor = minorVersion; 136 return this; 137 } 138 139 /** 140 * Associates different implementation of types. 141 * 142 * @param graphTypes implementation of types and enum recognition 143 * @return this builder 144 */ 145 public Builder<G, N, M> types(GraphTypes graphTypes) { 146 this.types = graphTypes; 147 return this; 148 } 149 150 /** 151 * Associates implementation of blocks. 152 * 153 * @param graphBlocks the blocks implementation 154 * @return this builder 155 */ 156 public Builder<G, N, M> blocks(GraphBlocks<G, ?, N> graphBlocks) { 157 this.blocks = graphBlocks; 158 return this; 159 } 160 161 /** 162 * Associates implementation of graph elements. 163 * 164 * @param graphElements the elements implementation 165 * @return this builder 166 */ 167 @SuppressWarnings({"unchecked", "rawtypes"}) 168 public <E> Builder<G, N, E> elements(GraphElements<E, ?, ?, ?> graphElements) { 169 this.elements = (GraphElements) graphElements; 170 return (Builder<G, N, E>) this; 171 } 172 173 /** 174 * Creates new {@link GraphOutput} to output to provided channel. The output will use 175 * interfaces currently associated with this builder. 176 * 177 * @param channel the channel to output to 178 * @return new graph output 179 * @throws IOException if something goes wrong when writing to the channel 180 */ 181 public GraphOutput<G, M> build(WritableByteChannel channel) throws IOException { 182 ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(major, minor, structure, types, blocks, elements, channel); 183 return new GraphOutput<>(p); 184 } 185 186 /** 187 * Support for nesting heterogenous graphs. The newly created output uses all the interfaces 188 * currently associated with this builder, but shares with {@code parent} the output 189 * {@code channel}, internal constant pool and {@link #protocolVersion(int, int) protocol 190 * version}. 191 * <p> 192 * Both GraphOutput (the {@code parent} and the returned one) has to be used in 193 * synchronization - e.g. only one 194 * {@link #beginGroup(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object, int, java.util.Map) 195 * begin}, {@link #endGroup() end} of group or 196 * {@link #print(java.lang.Object, java.util.Map, int, java.lang.String, java.lang.Object...) 197 * printing} can be on at a given moment. 198 * 199 * @param parent the output to inherit {@code channel} and protocol version from 200 * @return new output sharing {@code channel} and other internals with {@code parent} 201 */ 202 public GraphOutput<G, M> build(GraphOutput<?, ?> parent) { 203 ProtocolImpl<G, N, ?, ?, ?, M, ?, ?, ?> p = new ProtocolImpl<>(parent.printer, structure, types, blocks, elements); 204 return new GraphOutput<>(p); 205 } 206 } 207 }