--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java 2019-03-12 08:10:25.259895076 +0100 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java 2019-03-12 08:10:24.899892746 +0100 @@ -78,10 +78,12 @@ private final ConstantPool constantPool; private final ByteBuffer buffer; private final WritableByteChannel channel; + private final boolean embedded; final int versionMajor; final int versionMinor; + private boolean printing; - GraphProtocol(WritableByteChannel channel, int major, int minor) throws IOException { + GraphProtocol(WritableByteChannel channel, int major, int minor, boolean embedded) throws IOException { if (major > 6 || (major == 6 && minor > 0)) { throw new IllegalArgumentException("Unrecognized version " + major + "." + minor); } @@ -90,7 +92,11 @@ this.constantPool = new ConstantPool(); this.buffer = ByteBuffer.allocateDirect(256 * 1024); this.channel = channel; - writeVersion(); + this.embedded = embedded; + if (!embedded) { + writeVersion(); + flushEmbedded(); + } } GraphProtocol(GraphProtocol parent) { @@ -99,36 +105,67 @@ this.constantPool = parent.constantPool; this.buffer = parent.buffer; this.channel = parent.channel; + this.embedded = parent.embedded; } @SuppressWarnings("all") public final void print(Graph graph, Map properties, int id, String format, Object... args) throws IOException { - writeByte(BEGIN_GRAPH); - if (versionMajor >= 3) { - writeInt(id); - writeString(format); - writeInt(args.length); - for (Object a : args) { - writePropertyObject(graph, a); + printing = true; + try { + writeByte(BEGIN_GRAPH); + if (versionMajor >= 3) { + writeInt(id); + writeString(format); + writeInt(args.length); + for (Object a : args) { + writePropertyObject(graph, a); + } + } else { + writePoolObject(formatTitle(graph, id, format, args)); } - } else { - writePoolObject(formatTitle(graph, id, format, args)); + writeGraph(graph, properties); + flushEmbedded(); + flush(); + } finally { + printing = false; } - writeGraph(graph, properties); - flush(); } public final void beginGroup(Graph noGraph, String name, String shortName, ResolvedJavaMethod method, int bci, Map properties) throws IOException { - writeByte(BEGIN_GROUP); - writePoolObject(name); - writePoolObject(shortName); - writePoolObject(method); - writeInt(bci); - writeProperties(noGraph, properties); + printing = true; + try { + writeByte(BEGIN_GROUP); + writePoolObject(name); + writePoolObject(shortName); + writePoolObject(method); + writeInt(bci); + writeProperties(noGraph, properties); + flushEmbedded(); + } finally { + printing = false; + } } public final void endGroup() throws IOException { - writeByte(CLOSE_GROUP); + printing = true; + try { + writeByte(CLOSE_GROUP); + flushEmbedded(); + } finally { + printing = false; + } + } + + final int write(ByteBuffer src) throws IOException { + if (printing) { + throw new IllegalStateException("Trying to write during graph print."); + } + constantPool.reset(); + return writeBytesRaw(src); + } + + final boolean isOpen() { + return channel.isOpen(); } @Override @@ -280,6 +317,13 @@ writeByte(versionMinor); } + private void flushEmbedded() throws IOException { + if (embedded) { + flush(); + constantPool.reset(); + } + } + private void flush() throws IOException { buffer.flip(); /* @@ -358,6 +402,23 @@ } } + private int writeBytesRaw(ByteBuffer b) throws IOException { + int limit = b.limit(); + int written = 0; + while (b.position() < limit) { + int toWrite = Math.min(limit - b.position(), buffer.capacity()); + ensureAvailable(toWrite); + b.limit(b.position() + toWrite); + try { + buffer.put(b); + written += toWrite; + } finally { + b.limit(limit); + } + } + return written; + } + private void writeInts(int[] b) throws IOException { if (b == null) { writeInt(-1); @@ -818,6 +879,12 @@ put(obj, id); return id; } + + void reset() { + clear(); + availableIds.clear(); + nextId = 0; + } } }