src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java

Print this page




  23 package org.graalvm.compiler.printer;
  24 
  25 import static org.graalvm.compiler.graph.Edges.Type.Inputs;
  26 import static org.graalvm.compiler.graph.Edges.Type.Successors;
  27 
  28 import java.io.IOException;
  29 import java.nio.ByteBuffer;
  30 import java.nio.channels.WritableByteChannel;
  31 import java.nio.charset.Charset;
  32 import java.util.Arrays;
  33 import java.util.HashMap;
  34 import java.util.LinkedHashMap;
  35 import java.util.LinkedList;
  36 import java.util.List;
  37 import java.util.Map;
  38 import java.util.Map.Entry;
  39 
  40 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  41 import org.graalvm.compiler.bytecode.Bytecode;
  42 import org.graalvm.compiler.core.common.cfg.BlockMap;
  43 import org.graalvm.compiler.debug.Debug;
  44 import org.graalvm.compiler.debug.GraalDebugConfig.Options;
  45 import org.graalvm.compiler.graph.CachedGraph;
  46 import org.graalvm.compiler.graph.Edges;
  47 import org.graalvm.compiler.graph.Graph;
  48 import org.graalvm.compiler.graph.InputEdges;
  49 import org.graalvm.compiler.graph.Node;
  50 import org.graalvm.compiler.graph.NodeClass;
  51 import org.graalvm.compiler.graph.NodeList;
  52 import org.graalvm.compiler.graph.NodeMap;
  53 import org.graalvm.compiler.nodes.AbstractBeginNode;
  54 import org.graalvm.compiler.nodes.AbstractEndNode;
  55 import org.graalvm.compiler.nodes.AbstractMergeNode;
  56 import org.graalvm.compiler.nodes.ConstantNode;
  57 import org.graalvm.compiler.nodes.ControlSinkNode;
  58 import org.graalvm.compiler.nodes.ControlSplitNode;
  59 import org.graalvm.compiler.nodes.FixedNode;
  60 import org.graalvm.compiler.nodes.PhiNode;
  61 import org.graalvm.compiler.nodes.ProxyNode;
  62 import org.graalvm.compiler.nodes.StructuredGraph;
  63 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  64 import org.graalvm.compiler.nodes.VirtualState;
  65 import org.graalvm.compiler.nodes.cfg.Block;
  66 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
  67 import org.graalvm.compiler.phases.schedule.SchedulePhase;
  68 
  69 import jdk.vm.ci.meta.JavaType;
  70 import jdk.vm.ci.meta.ResolvedJavaField;
  71 import jdk.vm.ci.meta.ResolvedJavaMethod;
  72 import jdk.vm.ci.meta.Signature;
  73 import org.graalvm.compiler.graph.NodeSourcePosition;
  74 
  75 public class BinaryGraphPrinter implements GraphPrinter {
  76 
  77     private static final int CONSTANT_POOL_MAX_SIZE = 8000;
  78 
  79     private static final int BEGIN_GROUP = 0x00;
  80     private static final int BEGIN_GRAPH = 0x01;
  81     private static final int CLOSE_GROUP = 0x02;
  82 
  83     private static final int POOL_NEW = 0x00;
  84     private static final int POOL_STRING = 0x01;
  85     private static final int POOL_ENUM = 0x02;
  86     private static final int POOL_CLASS = 0x03;
  87     private static final int POOL_METHOD = 0x04;


 135             return false;
 136         }
 137 
 138         private Character nextAvailableId() {
 139             if (!availableIds.isEmpty()) {
 140                 return availableIds.removeFirst();
 141             }
 142             return nextId++;
 143         }
 144 
 145         public char add(Object obj) {
 146             Character id = nextAvailableId();
 147             put(obj, id);
 148             return id;
 149         }
 150     }
 151 
 152     private final ConstantPool constantPool;
 153     private final ByteBuffer buffer;
 154     private final WritableByteChannel channel;
 155     private SnippetReflectionProvider snippetReflection;
 156 
 157     private static final Charset utf8 = Charset.forName("UTF-8");
 158 
 159     public BinaryGraphPrinter(WritableByteChannel channel) throws IOException {
 160         constantPool = new ConstantPool();

 161         buffer = ByteBuffer.allocateDirect(256 * 1024);
 162         this.channel = channel;
 163         writeVersion();
 164     }
 165 
 166     @Override
 167     public void setSnippetReflectionProvider(SnippetReflectionProvider snippetReflection) {
 168         this.snippetReflection = snippetReflection;
 169     }
 170 
 171     @Override
 172     public SnippetReflectionProvider getSnippetReflectionProvider() {
 173         return snippetReflection;
 174     }
 175 
 176     @SuppressWarnings("all")
 177     @Override
 178     public void print(Graph graph, Map<Object, Object> properties, int id, String format, Object... args) throws IOException {
 179         writeByte(BEGIN_GRAPH);
 180         if (CURRENT_MAJOR_VERSION >= 3) {
 181             writeInt(id);
 182             writeString(format);
 183             writeInt(args.length);
 184             for (Object a : args) {
 185                 writePropertyObject(a);
 186             }
 187         } else {
 188             writePoolObject(formatTitle(id, format, args));
 189         }
 190         writeGraph(graph, properties);
 191         flush();
 192     }
 193 
 194     private void writeGraph(Graph graph, Map<Object, Object> properties) throws IOException {
 195         ScheduleResult scheduleResult = null;
 196         if (graph instanceof StructuredGraph) {
 197 
 198             StructuredGraph structuredGraph = (StructuredGraph) graph;
 199             scheduleResult = structuredGraph.getLastSchedule();
 200             if (scheduleResult == null) {
 201 
 202                 // Also provide a schedule when an error occurs
 203                 if (Options.PrintGraphWithSchedule.getValue(graph.getOptions()) || Debug.contextLookup(Throwable.class) != null) {
 204                     try {
 205                         SchedulePhase schedule = new SchedulePhase(graph.getOptions());
 206                         schedule.apply(structuredGraph);
 207                         scheduleResult = structuredGraph.getLastSchedule();
 208                     } catch (Throwable t) {
 209                     }
 210                 }
 211 
 212             }
 213         }
 214         ControlFlowGraph cfg = scheduleResult == null ? Debug.contextLookup(ControlFlowGraph.class) : scheduleResult.getCFG();
 215         BlockMap<List<Node>> blockToNodes = scheduleResult == null ? null : scheduleResult.getBlockToNodesMap();
 216         NodeMap<Block> nodeToBlocks = scheduleResult == null ? null : scheduleResult.getNodeToBlockMap();
 217         List<Block> blocks = cfg == null ? null : Arrays.asList(cfg.getBlocks());
 218         writeProperties(properties);
 219         writeNodes(graph, nodeToBlocks, cfg);
 220         writeBlocks(blocks, blockToNodes);
 221     }
 222 
 223     private void flush() throws IOException {
 224         buffer.flip();
 225         /*
 226          * Try not to let interrupted threads aborting the write. There's still a race here but an
 227          * interrupt that's been pending for a long time shouldn't stop this writing.
 228          */
 229         boolean interrupted = Thread.interrupted();
 230         try {
 231             channel.write(buffer);
 232         } finally {
 233             if (interrupted) {
 234                 Thread.currentThread().interrupt();
 235             }
 236         }
 237         buffer.compact();
 238     }
 239 
 240     private void ensureAvailable(int i) throws IOException {
 241         assert buffer.capacity() >= i : "Can not make " + i + " bytes available, buffer is too small";
 242         while (buffer.remaining() < i) {
 243             flush();
 244         }
 245     }
 246 


 421             writePoolObject(field.getType().getName());
 422             writeInt(field.getModifiers());
 423         } else if (object instanceof Signature) {
 424             writeByte(POOL_SIGNATURE);
 425             Signature signature = ((Signature) object);
 426             int args = signature.getParameterCount(false);
 427             writeShort((char) args);
 428             for (int i = 0; i < args; i++) {
 429                 writePoolObject(signature.getParameterType(i, null).getName());
 430             }
 431             writePoolObject(signature.getReturnType(null).getName());
 432         } else if (CURRENT_MAJOR_VERSION >= 4 && object instanceof NodeSourcePosition) {
 433             writeByte(POOL_NODE_SOURCE_POSITION);
 434             NodeSourcePosition pos = (NodeSourcePosition) object;
 435             ResolvedJavaMethod method = pos.getMethod();
 436             writePoolObject(method);
 437             final int bci = pos.getBCI();
 438             writeInt(bci);
 439             StackTraceElement ste = method.asStackTraceElement(bci);
 440             if (ste != null) {
 441                 writePoolObject(ste.getFileName());


 442                 writeInt(ste.getLineNumber());

 443             } else {
 444                 writePoolObject(null);
 445             }
 446             writePoolObject(pos.getCaller());
 447         } else {
 448             writeByte(POOL_STRING);
 449             writeString(object.toString());
 450         }
 451     }
 452 
 453     private void writeEdgesInfo(NodeClass<?> nodeClass, Edges.Type type) throws IOException {
 454         Edges edges = nodeClass.getEdges(type);
 455         writeShort((char) edges.getCount());
 456         for (int i = 0; i < edges.getCount(); i++) {
 457             writeByte(i < edges.getDirectCount() ? 0 : 1);
 458             writePoolObject(edges.getName(i));
 459             if (type == Inputs) {
 460                 writePoolObject(((InputEdges) edges).getInputType(i));
 461             }
 462         }
 463     }
 464 
 465     private void writePropertyObject(Object obj) throws IOException {
 466         if (obj instanceof Integer) {
 467             writeByte(PROPERTY_INT);
 468             writeInt(((Integer) obj).intValue());
 469         } else if (obj instanceof Long) {
 470             writeByte(PROPERTY_LONG);
 471             writeLong(((Long) obj).longValue());
 472         } else if (obj instanceof Double) {
 473             writeByte(PROPERTY_DOUBLE);
 474             writeDouble(((Double) obj).doubleValue());
 475         } else if (obj instanceof Float) {
 476             writeByte(PROPERTY_FLOAT);
 477             writeFloat(((Float) obj).floatValue());
 478         } else if (obj instanceof Boolean) {
 479             if (((Boolean) obj).booleanValue()) {
 480                 writeByte(PROPERTY_TRUE);
 481             } else {
 482                 writeByte(PROPERTY_FALSE);
 483             }
 484         } else if (obj instanceof Graph) {
 485             writeByte(PROPERTY_SUBGRAPH);
 486             writeGraph((Graph) obj, null);
 487         } else if (obj instanceof CachedGraph) {
 488             writeByte(PROPERTY_SUBGRAPH);
 489             writeGraph(((CachedGraph<?>) obj).getReadonlyCopy(), null);
 490         } else if (obj != null && obj.getClass().isArray()) {
 491             Class<?> componentType = obj.getClass().getComponentType();
 492             if (componentType.isPrimitive()) {
 493                 if (componentType == Double.TYPE) {
 494                     writeByte(PROPERTY_ARRAY);
 495                     writeByte(PROPERTY_DOUBLE);
 496                     writeDoubles((double[]) obj);
 497                 } else if (componentType == Integer.TYPE) {
 498                     writeByte(PROPERTY_ARRAY);
 499                     writeByte(PROPERTY_INT);
 500                     writeInts((int[]) obj);
 501                 } else {
 502                     writeByte(PROPERTY_POOL);
 503                     writePoolObject(obj);
 504                 }
 505             } else {
 506                 writeByte(PROPERTY_ARRAY);
 507                 writeByte(PROPERTY_POOL);
 508                 Object[] array = (Object[]) obj;
 509                 writeInt(array.length);


 519 
 520     @SuppressWarnings("deprecation")
 521     private static int getNodeId(Node node) {
 522         return node.getId();
 523     }
 524 
 525     private Object getBlockForNode(Node node, NodeMap<Block> nodeToBlocks) {
 526         if (nodeToBlocks.isNew(node)) {
 527             return "NEW (not in schedule)";
 528         } else {
 529             Block block = nodeToBlocks.get(node);
 530             if (block != null) {
 531                 return block.getId();
 532             } else if (node instanceof PhiNode) {
 533                 return getBlockForNode(((PhiNode) node).merge(), nodeToBlocks);
 534             }
 535         }
 536         return null;
 537     }
 538 
 539     private void writeNodes(Graph graph, NodeMap<Block> nodeToBlocks, ControlFlowGraph cfg) throws IOException {
 540         Map<Object, Object> props = new HashMap<>();
 541 
 542         writeInt(graph.getNodeCount());
 543 
 544         for (Node node : graph.getNodes()) {
 545             NodeClass<?> nodeClass = node.getNodeClass();
 546             node.getDebugProperties(props);
 547             if (cfg != null && Options.PrintGraphProbabilities.getValue(graph.getOptions()) && node instanceof FixedNode) {
 548                 try {
 549                     props.put("probability", cfg.blockFor(node).probability());
 550                 } catch (Throwable t) {
 551                     props.put("probability", 0.0);
 552                     props.put("probability-exception", t);
 553                 }
 554             }
 555 
 556             try {
 557                 props.put("NodeCost-Size", node.estimatedNodeSize());
 558                 props.put("NodeCost-Cycles", node.estimatedNodeCycles());
 559             } catch (Throwable t) {
 560                 props.put("node-cost-exception", t.getMessage());
 561             }
 562 
 563             if (nodeToBlocks != null) {
 564                 Object block = getBlockForNode(node, nodeToBlocks);
 565                 if (block != null) {
 566                     props.put("node-to-block", block);
 567                 }


 579                 props.put("category", "end");
 580             } else if (node instanceof FixedNode) {
 581                 props.put("category", "fixed");
 582             } else if (node instanceof VirtualState) {
 583                 props.put("category", "state");
 584             } else if (node instanceof PhiNode) {
 585                 props.put("category", "phi");
 586             } else if (node instanceof ProxyNode) {
 587                 props.put("category", "proxy");
 588             } else {
 589                 if (node instanceof ConstantNode) {
 590                     ConstantNode cn = (ConstantNode) node;
 591                     updateStringPropertiesForConstant(props, cn);
 592                 }
 593                 props.put("category", "floating");
 594             }
 595 
 596             writeInt(getNodeId(node));
 597             writePoolObject(nodeClass);
 598             writeByte(node.predecessor() == null ? 0 : 1);
 599             writeProperties(props);
 600             writeEdges(node, Inputs);
 601             writeEdges(node, Successors);
 602 
 603             props.clear();
 604         }
 605     }
 606 
 607     private void writeProperties(Map<Object, Object> props) throws IOException {
 608         if (props == null) {
 609             writeShort((char) 0);
 610             return;
 611         }
 612         // properties
 613         writeShort((char) props.size());
 614         for (Entry<Object, Object> entry : props.entrySet()) {
 615             String key = entry.getKey().toString();
 616             writePoolObject(key);
 617             writePropertyObject(entry.getValue());
 618         }
 619     }
 620 
 621     private void writeEdges(Node node, Edges.Type type) throws IOException {
 622         NodeClass<?> nodeClass = node.getNodeClass();
 623         Edges edges = nodeClass.getEdges(type);
 624         final long[] curOffsets = edges.getOffsets();
 625         for (int i = 0; i < edges.getDirectCount(); i++) {
 626             writeNodeRef(Edges.getNode(node, curOffsets, i));
 627         }
 628         for (int i = edges.getDirectCount(); i < edges.getCount(); i++) {
 629             NodeList<Node> list = Edges.getNodeList(node, curOffsets, i);
 630             if (list == null) {
 631                 writeShort((char) 0);
 632             } else {
 633                 int listSize = list.count();
 634                 assert listSize == ((char) listSize);
 635                 writeShort((char) listSize);
 636                 for (Node edge : list) {
 637                     writeNodeRef(edge);


 673                     }
 674                 }
 675                 writeInt(nodes.size() + extraNodes.size());
 676                 for (Node node : nodes) {
 677                     writeInt(getNodeId(node));
 678                 }
 679                 for (Node node : extraNodes) {
 680                     writeInt(getNodeId(node));
 681                 }
 682                 writeInt(block.getSuccessors().length);
 683                 for (Block sux : block.getSuccessors()) {
 684                     writeInt(sux.getId());
 685                 }
 686             }
 687         } else {
 688             writeInt(0);
 689         }
 690     }
 691 
 692     @Override
 693     public void beginGroup(String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) throws IOException {
 694         writeByte(BEGIN_GROUP);
 695         writePoolObject(name);
 696         writePoolObject(shortName);
 697         writePoolObject(method);
 698         writeInt(bci);
 699         writeProperties(properties);
 700     }
 701 
 702     @Override
 703     public void endGroup() throws IOException {
 704         writeByte(CLOSE_GROUP);
 705     }
 706 
 707     @Override
 708     public void close() {
 709         try {
 710             flush();
 711             channel.close();
 712         } catch (IOException ex) {
 713             throw new Error(ex);
 714         }
 715     }
 716 }


  23 package org.graalvm.compiler.printer;
  24 
  25 import static org.graalvm.compiler.graph.Edges.Type.Inputs;
  26 import static org.graalvm.compiler.graph.Edges.Type.Successors;
  27 
  28 import java.io.IOException;
  29 import java.nio.ByteBuffer;
  30 import java.nio.channels.WritableByteChannel;
  31 import java.nio.charset.Charset;
  32 import java.util.Arrays;
  33 import java.util.HashMap;
  34 import java.util.LinkedHashMap;
  35 import java.util.LinkedList;
  36 import java.util.List;
  37 import java.util.Map;
  38 import java.util.Map.Entry;
  39 
  40 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  41 import org.graalvm.compiler.bytecode.Bytecode;
  42 import org.graalvm.compiler.core.common.cfg.BlockMap;
  43 import org.graalvm.compiler.debug.DebugContext;
  44 import org.graalvm.compiler.debug.DebugOptions;
  45 import org.graalvm.compiler.graph.CachedGraph;
  46 import org.graalvm.compiler.graph.Edges;
  47 import org.graalvm.compiler.graph.Graph;
  48 import org.graalvm.compiler.graph.InputEdges;
  49 import org.graalvm.compiler.graph.Node;
  50 import org.graalvm.compiler.graph.NodeClass;
  51 import org.graalvm.compiler.graph.NodeList;
  52 import org.graalvm.compiler.graph.NodeMap;
  53 import org.graalvm.compiler.nodes.AbstractBeginNode;
  54 import org.graalvm.compiler.nodes.AbstractEndNode;
  55 import org.graalvm.compiler.nodes.AbstractMergeNode;
  56 import org.graalvm.compiler.nodes.ConstantNode;
  57 import org.graalvm.compiler.nodes.ControlSinkNode;
  58 import org.graalvm.compiler.nodes.ControlSplitNode;
  59 import org.graalvm.compiler.nodes.FixedNode;
  60 import org.graalvm.compiler.nodes.PhiNode;
  61 import org.graalvm.compiler.nodes.ProxyNode;

  62 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
  63 import org.graalvm.compiler.nodes.VirtualState;
  64 import org.graalvm.compiler.nodes.cfg.Block;
  65 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;

  66 
  67 import jdk.vm.ci.meta.JavaType;
  68 import jdk.vm.ci.meta.ResolvedJavaField;
  69 import jdk.vm.ci.meta.ResolvedJavaMethod;
  70 import jdk.vm.ci.meta.Signature;
  71 import org.graalvm.compiler.graph.NodeSourcePosition;
  72 
  73 public class BinaryGraphPrinter implements GraphPrinter {
  74 
  75     private static final int CONSTANT_POOL_MAX_SIZE = 8000;
  76 
  77     private static final int BEGIN_GROUP = 0x00;
  78     private static final int BEGIN_GRAPH = 0x01;
  79     private static final int CLOSE_GROUP = 0x02;
  80 
  81     private static final int POOL_NEW = 0x00;
  82     private static final int POOL_STRING = 0x01;
  83     private static final int POOL_ENUM = 0x02;
  84     private static final int POOL_CLASS = 0x03;
  85     private static final int POOL_METHOD = 0x04;


 133             return false;
 134         }
 135 
 136         private Character nextAvailableId() {
 137             if (!availableIds.isEmpty()) {
 138                 return availableIds.removeFirst();
 139             }
 140             return nextId++;
 141         }
 142 
 143         public char add(Object obj) {
 144             Character id = nextAvailableId();
 145             put(obj, id);
 146             return id;
 147         }
 148     }
 149 
 150     private final ConstantPool constantPool;
 151     private final ByteBuffer buffer;
 152     private final WritableByteChannel channel;
 153     private final SnippetReflectionProvider snippetReflection;
 154 
 155     private static final Charset utf8 = Charset.forName("UTF-8");
 156 
 157     public BinaryGraphPrinter(WritableByteChannel channel, SnippetReflectionProvider snippetReflection) throws IOException {
 158         constantPool = new ConstantPool();
 159         this.snippetReflection = snippetReflection;
 160         buffer = ByteBuffer.allocateDirect(256 * 1024);
 161         this.channel = channel;
 162         writeVersion();
 163     }
 164 
 165     @Override





 166     public SnippetReflectionProvider getSnippetReflectionProvider() {
 167         return snippetReflection;
 168     }
 169 
 170     @SuppressWarnings("all")
 171     @Override
 172     public void print(DebugContext debug, Graph graph, Map<Object, Object> properties, int id, String format, Object... args) throws IOException {
 173         writeByte(BEGIN_GRAPH);
 174         if (CURRENT_MAJOR_VERSION >= 3) {
 175             writeInt(id);
 176             writeString(format);
 177             writeInt(args.length);
 178             for (Object a : args) {
 179                 writePropertyObject(debug, a);
 180             }
 181         } else {
 182             writePoolObject(id + ": " + String.format(format, simplifyClassArgs(args)));
 183         }
 184         writeGraph(debug, graph, properties);
 185         flush();
 186     }
 187 
 188     private void writeGraph(DebugContext debug, Graph graph, Map<Object, Object> properties) throws IOException {
 189         boolean needSchedule = DebugOptions.PrintGraphWithSchedule.getValue(graph.getOptions()) || debug.contextLookup(Throwable.class) != null;
 190         ScheduleResult scheduleResult = needSchedule ? GraphPrinter.getScheduleOrNull(graph) : null;
 191         ControlFlowGraph cfg = scheduleResult == null ? debug.contextLookup(ControlFlowGraph.class) : scheduleResult.getCFG();

















 192         BlockMap<List<Node>> blockToNodes = scheduleResult == null ? null : scheduleResult.getBlockToNodesMap();
 193         NodeMap<Block> nodeToBlocks = scheduleResult == null ? null : scheduleResult.getNodeToBlockMap();
 194         List<Block> blocks = cfg == null ? null : Arrays.asList(cfg.getBlocks());
 195         writeProperties(debug, properties);
 196         writeNodes(debug, graph, nodeToBlocks, cfg);
 197         writeBlocks(blocks, blockToNodes);
 198     }
 199 
 200     private void flush() throws IOException {
 201         buffer.flip();
 202         /*
 203          * Try not to let interrupted threads abort the write. There's still a race here but an
 204          * interrupt that's been pending for a long time shouldn't stop this writing.
 205          */
 206         boolean interrupted = Thread.interrupted();
 207         try {
 208             channel.write(buffer);
 209         } finally {
 210             if (interrupted) {
 211                 Thread.currentThread().interrupt();
 212             }
 213         }
 214         buffer.compact();
 215     }
 216 
 217     private void ensureAvailable(int i) throws IOException {
 218         assert buffer.capacity() >= i : "Can not make " + i + " bytes available, buffer is too small";
 219         while (buffer.remaining() < i) {
 220             flush();
 221         }
 222     }
 223 


 398             writePoolObject(field.getType().getName());
 399             writeInt(field.getModifiers());
 400         } else if (object instanceof Signature) {
 401             writeByte(POOL_SIGNATURE);
 402             Signature signature = ((Signature) object);
 403             int args = signature.getParameterCount(false);
 404             writeShort((char) args);
 405             for (int i = 0; i < args; i++) {
 406                 writePoolObject(signature.getParameterType(i, null).getName());
 407             }
 408             writePoolObject(signature.getReturnType(null).getName());
 409         } else if (CURRENT_MAJOR_VERSION >= 4 && object instanceof NodeSourcePosition) {
 410             writeByte(POOL_NODE_SOURCE_POSITION);
 411             NodeSourcePosition pos = (NodeSourcePosition) object;
 412             ResolvedJavaMethod method = pos.getMethod();
 413             writePoolObject(method);
 414             final int bci = pos.getBCI();
 415             writeInt(bci);
 416             StackTraceElement ste = method.asStackTraceElement(bci);
 417             if (ste != null) {
 418                 String fn = ste.getFileName();
 419                 writePoolObject(fn);
 420                 if (fn != null) {
 421                     writeInt(ste.getLineNumber());
 422                 }
 423             } else {
 424                 writePoolObject(null);
 425             }
 426             writePoolObject(pos.getCaller());
 427         } else {
 428             writeByte(POOL_STRING);
 429             writeString(object.toString());
 430         }
 431     }
 432 
 433     private void writeEdgesInfo(NodeClass<?> nodeClass, Edges.Type type) throws IOException {
 434         Edges edges = nodeClass.getEdges(type);
 435         writeShort((char) edges.getCount());
 436         for (int i = 0; i < edges.getCount(); i++) {
 437             writeByte(i < edges.getDirectCount() ? 0 : 1);
 438             writePoolObject(edges.getName(i));
 439             if (type == Inputs) {
 440                 writePoolObject(((InputEdges) edges).getInputType(i));
 441             }
 442         }
 443     }
 444 
 445     private void writePropertyObject(DebugContext debug, Object obj) throws IOException {
 446         if (obj instanceof Integer) {
 447             writeByte(PROPERTY_INT);
 448             writeInt(((Integer) obj).intValue());
 449         } else if (obj instanceof Long) {
 450             writeByte(PROPERTY_LONG);
 451             writeLong(((Long) obj).longValue());
 452         } else if (obj instanceof Double) {
 453             writeByte(PROPERTY_DOUBLE);
 454             writeDouble(((Double) obj).doubleValue());
 455         } else if (obj instanceof Float) {
 456             writeByte(PROPERTY_FLOAT);
 457             writeFloat(((Float) obj).floatValue());
 458         } else if (obj instanceof Boolean) {
 459             if (((Boolean) obj).booleanValue()) {
 460                 writeByte(PROPERTY_TRUE);
 461             } else {
 462                 writeByte(PROPERTY_FALSE);
 463             }
 464         } else if (obj instanceof Graph) {
 465             writeByte(PROPERTY_SUBGRAPH);
 466             writeGraph(debug, (Graph) obj, null);
 467         } else if (obj instanceof CachedGraph) {
 468             writeByte(PROPERTY_SUBGRAPH);
 469             writeGraph(debug, ((CachedGraph<?>) obj).getReadonlyCopy(), null);
 470         } else if (obj != null && obj.getClass().isArray()) {
 471             Class<?> componentType = obj.getClass().getComponentType();
 472             if (componentType.isPrimitive()) {
 473                 if (componentType == Double.TYPE) {
 474                     writeByte(PROPERTY_ARRAY);
 475                     writeByte(PROPERTY_DOUBLE);
 476                     writeDoubles((double[]) obj);
 477                 } else if (componentType == Integer.TYPE) {
 478                     writeByte(PROPERTY_ARRAY);
 479                     writeByte(PROPERTY_INT);
 480                     writeInts((int[]) obj);
 481                 } else {
 482                     writeByte(PROPERTY_POOL);
 483                     writePoolObject(obj);
 484                 }
 485             } else {
 486                 writeByte(PROPERTY_ARRAY);
 487                 writeByte(PROPERTY_POOL);
 488                 Object[] array = (Object[]) obj;
 489                 writeInt(array.length);


 499 
 500     @SuppressWarnings("deprecation")
 501     private static int getNodeId(Node node) {
 502         return node.getId();
 503     }
 504 
 505     private Object getBlockForNode(Node node, NodeMap<Block> nodeToBlocks) {
 506         if (nodeToBlocks.isNew(node)) {
 507             return "NEW (not in schedule)";
 508         } else {
 509             Block block = nodeToBlocks.get(node);
 510             if (block != null) {
 511                 return block.getId();
 512             } else if (node instanceof PhiNode) {
 513                 return getBlockForNode(((PhiNode) node).merge(), nodeToBlocks);
 514             }
 515         }
 516         return null;
 517     }
 518 
 519     private void writeNodes(DebugContext debug, Graph graph, NodeMap<Block> nodeToBlocks, ControlFlowGraph cfg) throws IOException {
 520         Map<Object, Object> props = new HashMap<>();
 521 
 522         writeInt(graph.getNodeCount());
 523 
 524         for (Node node : graph.getNodes()) {
 525             NodeClass<?> nodeClass = node.getNodeClass();
 526             node.getDebugProperties(props);
 527             if (cfg != null && DebugOptions.PrintGraphProbabilities.getValue(graph.getOptions()) && node instanceof FixedNode) {
 528                 try {
 529                     props.put("probability", cfg.blockFor(node).probability());
 530                 } catch (Throwable t) {
 531                     props.put("probability", 0.0);
 532                     props.put("probability-exception", t);
 533                 }
 534             }
 535 
 536             try {
 537                 props.put("NodeCost-Size", node.estimatedNodeSize());
 538                 props.put("NodeCost-Cycles", node.estimatedNodeCycles());
 539             } catch (Throwable t) {
 540                 props.put("node-cost-exception", t.getMessage());
 541             }
 542 
 543             if (nodeToBlocks != null) {
 544                 Object block = getBlockForNode(node, nodeToBlocks);
 545                 if (block != null) {
 546                     props.put("node-to-block", block);
 547                 }


 559                 props.put("category", "end");
 560             } else if (node instanceof FixedNode) {
 561                 props.put("category", "fixed");
 562             } else if (node instanceof VirtualState) {
 563                 props.put("category", "state");
 564             } else if (node instanceof PhiNode) {
 565                 props.put("category", "phi");
 566             } else if (node instanceof ProxyNode) {
 567                 props.put("category", "proxy");
 568             } else {
 569                 if (node instanceof ConstantNode) {
 570                     ConstantNode cn = (ConstantNode) node;
 571                     updateStringPropertiesForConstant(props, cn);
 572                 }
 573                 props.put("category", "floating");
 574             }
 575 
 576             writeInt(getNodeId(node));
 577             writePoolObject(nodeClass);
 578             writeByte(node.predecessor() == null ? 0 : 1);
 579             writeProperties(debug, props);
 580             writeEdges(node, Inputs);
 581             writeEdges(node, Successors);
 582 
 583             props.clear();
 584         }
 585     }
 586 
 587     private void writeProperties(DebugContext debug, Map<Object, Object> props) throws IOException {
 588         if (props == null) {
 589             writeShort((char) 0);
 590             return;
 591         }
 592         // properties
 593         writeShort((char) props.size());
 594         for (Entry<Object, Object> entry : props.entrySet()) {
 595             String key = entry.getKey().toString();
 596             writePoolObject(key);
 597             writePropertyObject(debug, entry.getValue());
 598         }
 599     }
 600 
 601     private void writeEdges(Node node, Edges.Type type) throws IOException {
 602         NodeClass<?> nodeClass = node.getNodeClass();
 603         Edges edges = nodeClass.getEdges(type);
 604         final long[] curOffsets = edges.getOffsets();
 605         for (int i = 0; i < edges.getDirectCount(); i++) {
 606             writeNodeRef(Edges.getNode(node, curOffsets, i));
 607         }
 608         for (int i = edges.getDirectCount(); i < edges.getCount(); i++) {
 609             NodeList<Node> list = Edges.getNodeList(node, curOffsets, i);
 610             if (list == null) {
 611                 writeShort((char) 0);
 612             } else {
 613                 int listSize = list.count();
 614                 assert listSize == ((char) listSize);
 615                 writeShort((char) listSize);
 616                 for (Node edge : list) {
 617                     writeNodeRef(edge);


 653                     }
 654                 }
 655                 writeInt(nodes.size() + extraNodes.size());
 656                 for (Node node : nodes) {
 657                     writeInt(getNodeId(node));
 658                 }
 659                 for (Node node : extraNodes) {
 660                     writeInt(getNodeId(node));
 661                 }
 662                 writeInt(block.getSuccessors().length);
 663                 for (Block sux : block.getSuccessors()) {
 664                     writeInt(sux.getId());
 665                 }
 666             }
 667         } else {
 668             writeInt(0);
 669         }
 670     }
 671 
 672     @Override
 673     public void beginGroup(DebugContext debug, String name, String shortName, ResolvedJavaMethod method, int bci, Map<Object, Object> properties) throws IOException {
 674         writeByte(BEGIN_GROUP);
 675         writePoolObject(name);
 676         writePoolObject(shortName);
 677         writePoolObject(method);
 678         writeInt(bci);
 679         writeProperties(debug, properties);
 680     }
 681 
 682     @Override
 683     public void endGroup() throws IOException {
 684         writeByte(CLOSE_GROUP);
 685     }
 686 
 687     @Override
 688     public void close() {
 689         try {
 690             flush();
 691             channel.close();
 692         } catch (IOException ex) {
 693             throw new Error(ex);
 694         }
 695     }
 696 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File