src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.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/GraphPrinterDumpHandler.java

Print this page




   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.compiler.printer;
  24 
  25 import static org.graalvm.compiler.debug.GraalDebugConfig.asJavaMethod;
  26 
  27 import java.io.IOException;
  28 import java.lang.management.ManagementFactory;
  29 import java.nio.channels.ClosedByInterruptException;
  30 import java.util.ArrayList;
  31 import java.util.Arrays;
  32 import java.util.Collections;
  33 import java.util.Date;
  34 import java.util.HashMap;
  35 import java.util.List;
  36 import java.util.Map;
  37 import java.util.WeakHashMap;
  38 
  39 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  40 import org.graalvm.compiler.debug.Debug;
  41 import org.graalvm.compiler.debug.Debug.Scope;
  42 import org.graalvm.compiler.debug.DebugConfig;
  43 import org.graalvm.compiler.debug.DebugDumpHandler;
  44 import org.graalvm.compiler.debug.DebugDumpScope;
  45 import org.graalvm.compiler.debug.GraalDebugConfig;
  46 import org.graalvm.compiler.debug.GraalDebugConfig.Options;
  47 import org.graalvm.compiler.debug.GraalError;
  48 import org.graalvm.compiler.debug.TTY;
  49 import org.graalvm.compiler.debug.internal.DebugScope;
  50 import org.graalvm.compiler.graph.Graph;
  51 import org.graalvm.compiler.nodes.StructuredGraph;

  52 import org.graalvm.compiler.phases.contract.NodeCostUtil;
  53 
  54 import jdk.vm.ci.meta.JavaMethod;
  55 import jdk.vm.ci.meta.ResolvedJavaMethod;
  56 
  57 //JaCoCo Exclude
  58 
  59 /**
  60  * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
  61  * that can be inspected with the <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>
  62  * .
  63  */
  64 public class GraphPrinterDumpHandler implements DebugDumpHandler {
  65 
  66     private static final int FAILURE_LIMIT = 8;
  67     private final GraphPrinterSupplier printerSupplier;
  68     protected GraphPrinter printer;
  69     private SnippetReflectionProvider snippetReflection;
  70     private List<String> previousInlineContext;
  71     private int[] dumpIds = {};
  72     private int failuresCount;
  73     private Map<Graph, List<String>> inlineContextMap;
  74     private final String jvmArguments;
  75     private final String sunJavaCommand;
  76 
  77     @FunctionalInterface
  78     public interface GraphPrinterSupplier {
  79         GraphPrinter get() throws IOException;
  80     }
  81 
  82     /**
  83      * Creates a new {@link GraphPrinterDumpHandler}.
  84      *
  85      * @param printerSupplier Supplier used to create the GraphPrinter. Should supply an optional or
  86      *            null in case of failure.
  87      */
  88     public GraphPrinterDumpHandler(GraphPrinterSupplier printerSupplier) {
  89         this.printerSupplier = printerSupplier;
  90         /* Add the JVM and Java arguments to the graph properties to help identify it. */
  91         this.jvmArguments = String.join(" ", ManagementFactory.getRuntimeMXBean().getInputArguments());
  92         this.sunJavaCommand = System.getProperty("sun.java.command");
  93     }
  94 
  95     private void ensureInitialized() {
  96         if (printer == null) {
  97             if (failuresCount >= FAILURE_LIMIT) {
  98                 return;
  99             }
 100             previousInlineContext = new ArrayList<>();
 101             inlineContextMap = new WeakHashMap<>();

 102             try {
 103                 printer = printerSupplier.get();
 104                 if (snippetReflection != null) {
 105                     printer.setSnippetReflectionProvider(snippetReflection);
 106                 }
 107             } catch (IOException e) {
 108                 handleException(e);
 109             }
 110         }
 111     }
 112 
 113     private int nextDumpId() {
 114         int depth = previousInlineContext.size();
 115         if (dumpIds.length < depth) {
 116             dumpIds = Arrays.copyOf(dumpIds, depth);
 117         }
 118         return dumpIds[depth - 1]++;
 119     }
 120 
 121     @Override
 122     @SuppressWarnings("try")
 123     public void dump(Object object, final String format, Object... arguments) {
 124         if (object instanceof Graph && Options.PrintGraph.getValue(DebugScope.getConfig().getOptions())) {
 125             ensureInitialized();


 126             if (printer == null) {
 127                 return;
 128             }
 129             final Graph graph = (Graph) object;
 130 
 131             // Get all current JavaMethod instances in the context.
 132             List<String> inlineContext = getInlineContext(graph);
 133 
 134             if (inlineContext != previousInlineContext) {
 135                 Map<Object, Object> properties = new HashMap<>();
 136                 properties.put("graph", graph.toString());
 137                 addCompilationId(properties, graph);
 138                 addCFGFileName(properties);
 139                 if (inlineContext.equals(previousInlineContext)) {
 140                     /*
 141                      * two different graphs have the same inline context, so make sure they appear
 142                      * in different folders by closing and reopening the top scope.
 143                      */
 144                     int inlineDepth = previousInlineContext.size() - 1;
 145                     closeScope(inlineDepth);
 146                     openScope(inlineContext.get(inlineDepth), inlineDepth, properties);
 147                 } else {
 148                     // Check for method scopes that must be closed since the previous dump.
 149                     for (int i = 0; i < previousInlineContext.size(); ++i) {
 150                         if (i >= inlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
 151                             for (int inlineDepth = previousInlineContext.size() - 1; inlineDepth >= i; --inlineDepth) {
 152                                 closeScope(inlineDepth);
 153                             }
 154                             break;
 155                         }
 156                     }
 157                     // Check for method scopes that must be opened since the previous dump.
 158                     for (int i = 0; i < inlineContext.size(); ++i) {
 159                         if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
 160                             for (int inlineDepth = i; inlineDepth < inlineContext.size(); ++inlineDepth) {
 161                                 openScope(inlineContext.get(inlineDepth), inlineDepth, inlineDepth == inlineContext.size() - 1 ? properties : null);
 162                             }
 163                             break;
 164                         }
 165                     }
 166                 }
 167             }
 168 
 169             // Save inline context for next dump.
 170             previousInlineContext = inlineContext;
 171 
 172             try (Scope s = Debug.sandbox("PrintingGraph", null)) {
 173                 // Finally, output the graph.
 174                 Map<Object, Object> properties = new HashMap<>();
 175                 properties.put("graph", graph.toString());
 176                 properties.put("scope", Debug.currentScope());
 177                 if (graph instanceof StructuredGraph) {
 178                     properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId());
 179                     try {
 180                         int size = NodeCostUtil.computeGraphSize((StructuredGraph) graph);
 181                         properties.put("node-cost graph size", size);
 182                     } catch (Throwable t) {
 183                         properties.put("node-cost-exception", t.getMessage());
 184                     }
 185                 }
 186                 addCFGFileName(properties);
 187                 printer.print(graph, properties, nextDumpId(), format, arguments);
 188             } catch (IOException e) {
 189                 handleException(e);
 190             } catch (Throwable e) {
 191                 throw Debug.handle(e);
 192             }
 193         }
 194     }
 195 
 196     void handleException(IOException e) {
 197         if (GraalDebugConfig.Options.DumpingErrorsAreFatal.getValue(DebugScope.getConfig().getOptions())) {
 198             throw new GraalError(e);
 199         }
 200         if (e instanceof ClosedByInterruptException) {
 201             /*
 202              * The current dumping was aborted by an interrupt so treat this as a transient failure.
 203              */
 204             failuresCount = 0;
 205         } else {
 206             failuresCount++;
 207         }
 208         printer = null;
 209         if (failuresCount > FAILURE_LIMIT) {
 210             e.printStackTrace(TTY.out);

 211             TTY.println("Too many failures with dumping.  Disabling dump in thread " + Thread.currentThread());
 212         } else {
 213             TTY.println(e.getMessage());
 214         }
 215     }
 216 
 217     private static void addCompilationId(Map<Object, Object> properties, final Graph graph) {
 218         if (graph instanceof StructuredGraph) {
 219             properties.put("compilationId", ((StructuredGraph) graph).compilationId());
 220         }
 221     }
 222 
 223     private static void addCFGFileName(Map<Object, Object> properties) {
 224         DebugConfig config = DebugScope.getConfig();
 225         if (config != null) {
 226             for (DebugDumpHandler dumpHandler : config.dumpHandlers()) {
 227                 if (dumpHandler instanceof CFGPrinterObserver) {
 228                     CFGPrinterObserver cfg = (CFGPrinterObserver) dumpHandler;
 229                     String path = cfg.getDumpPath();
 230                     if (path != null) {
 231                         properties.put("PrintCFGFileName", path);
 232                     }
 233                     return;
 234                 }
 235             }
 236         }
 237     }
 238 
 239     private List<String> getInlineContext(Graph graph) {
 240         List<String> result = inlineContextMap.get(graph);
 241         if (result == null) {
 242             result = new ArrayList<>();
 243             Object lastMethodOrGraph = null;
 244             boolean graphSeen = false;
 245             for (Object o : Debug.context()) {

 246                 if (o == graph) {
 247                     graphSeen = true;
 248                 }
 249 
 250                 if (o instanceof DebugDumpScope) {
 251                     DebugDumpScope debugDumpScope = (DebugDumpScope) o;
 252                     if (debugDumpScope.decorator && !result.isEmpty()) {
 253                         result.set(result.size() - 1, debugDumpScope.name + ":" + result.get(result.size() - 1));
 254                     } else {
 255                         result.add(debugDumpScope.name);
 256                     }
 257                 } else {
 258                     addMethodContext(result, o, lastMethodOrGraph);
 259                 }
 260                 if (o instanceof JavaMethod || o instanceof Graph) {
 261                     lastMethodOrGraph = o;
 262                 }
 263             }
 264 
 265             if (result.isEmpty()) {


 290             /*
 291              * Include the current method in the context if there was no previous JavaMethod or
 292              * JavaMethodContext or if the method is different or if the method is the same but it
 293              * comes from two different graphs. This ensures that recursive call patterns are
 294              * handled properly.
 295              */
 296             if (lastMethodOrGraph == null || asJavaMethod(lastMethodOrGraph) == null || !asJavaMethod(lastMethodOrGraph).equals(method) ||
 297                             (lastMethodOrGraph != o && lastMethodOrGraph instanceof Graph && o instanceof Graph)) {
 298                 result.add(method.format("%H.%n(%p)"));
 299             } else {
 300                 /*
 301                  * This prevents multiple adjacent method context objects for the same method from
 302                  * resulting in multiple IGV tree levels. This works on the assumption that real
 303                  * inlining debug scopes will have a graph context object between the inliner and
 304                  * inlinee context objects.
 305                  */
 306             }
 307         }
 308     }
 309 
 310     private void openScope(String name, int inlineDepth, Map<Object, Object> properties) {
 311         try {
 312             Map<Object, Object> props = properties;
 313             if (inlineDepth == 0) {
 314                 /* Include some VM specific properties at the root. */
 315                 if (props == null) {
 316                     props = new HashMap<>();
 317                 }
 318                 props.put("jvmArguments", jvmArguments);
 319                 if (sunJavaCommand != null) {
 320                     props.put("sun.java.command", sunJavaCommand);
 321                 }
 322                 props.put("date", new Date().toString());
 323             }
 324             printer.beginGroup(name, name, Debug.contextLookup(ResolvedJavaMethod.class), -1, props);
 325         } catch (IOException e) {
 326             handleException(e);
 327         }
 328     }
 329 
 330     private void closeScope(int inlineDepth) {
 331         dumpIds[inlineDepth] = 0;
 332         try {

 333             printer.endGroup();

 334         } catch (IOException e) {
 335             handleException(e);
 336         }
 337     }
 338 
 339     @Override
 340     public void close() {
 341         if (previousInlineContext != null) {
 342             for (int inlineDepth = 0; inlineDepth < previousInlineContext.size(); inlineDepth++) {
 343                 closeScope(inlineDepth);
 344             }
 345         }
 346         if (printer != null) {
 347             printer.close();
 348             printer = null;
 349         }
 350     }
 351 
 352     @Override
 353     public void addCapability(Object capability) {
 354         if (capability instanceof SnippetReflectionProvider) {
 355             snippetReflection = (SnippetReflectionProvider) capability;
 356             if (printer != null && printer.getSnippetReflectionProvider() == null) {
 357                 printer.setSnippetReflectionProvider(snippetReflection);
 358             }
 359         }
 360     }
 361 }


   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.compiler.printer;
  24 
  25 import static org.graalvm.compiler.debug.DebugConfig.asJavaMethod;
  26 
  27 import java.io.IOException;
  28 import java.lang.management.ManagementFactory;
  29 import java.nio.channels.ClosedByInterruptException;
  30 import java.util.ArrayList;
  31 import java.util.Arrays;
  32 import java.util.Collections;
  33 import java.util.Date;
  34 import java.util.HashMap;
  35 import java.util.List;
  36 import java.util.Map;
  37 import java.util.WeakHashMap;
  38 
  39 import org.graalvm.compiler.debug.DebugContext;



  40 import org.graalvm.compiler.debug.DebugDumpHandler;
  41 import org.graalvm.compiler.debug.DebugDumpScope;
  42 import org.graalvm.compiler.debug.DebugOptions;

  43 import org.graalvm.compiler.debug.GraalError;
  44 import org.graalvm.compiler.debug.TTY;

  45 import org.graalvm.compiler.graph.Graph;
  46 import org.graalvm.compiler.nodes.StructuredGraph;
  47 import org.graalvm.compiler.options.OptionValues;
  48 import org.graalvm.compiler.phases.contract.NodeCostUtil;
  49 
  50 import jdk.vm.ci.meta.JavaMethod;
  51 import jdk.vm.ci.meta.ResolvedJavaMethod;
  52 
  53 //JaCoCo Exclude
  54 
  55 /**
  56  * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
  57  * that can be inspected with the Graph Visualizer.

  58  */
  59 public class GraphPrinterDumpHandler implements DebugDumpHandler {
  60 
  61     private static final int FAILURE_LIMIT = 8;
  62     private final GraphPrinterSupplier printerSupplier;
  63     protected GraphPrinter printer;

  64     private List<String> previousInlineContext;
  65     private int[] dumpIds = {};
  66     private int failuresCount;
  67     private Map<Graph, List<String>> inlineContextMap;
  68     private final String jvmArguments;
  69     private final String sunJavaCommand;
  70 
  71     @FunctionalInterface
  72     public interface GraphPrinterSupplier {
  73         GraphPrinter get(Graph graph) throws IOException;
  74     }
  75 
  76     /**
  77      * Creates a new {@link GraphPrinterDumpHandler}.
  78      *
  79      * @param printerSupplier Supplier used to create the GraphPrinter. Should supply an optional or
  80      *            null in case of failure.
  81      */
  82     public GraphPrinterDumpHandler(GraphPrinterSupplier printerSupplier) {
  83         this.printerSupplier = printerSupplier;
  84         /* Add the JVM and Java arguments to the graph properties to help identify it. */
  85         this.jvmArguments = String.join(" ", ManagementFactory.getRuntimeMXBean().getInputArguments());
  86         this.sunJavaCommand = System.getProperty("sun.java.command");
  87     }
  88 
  89     private void ensureInitialized(Graph graph) {
  90         if (printer == null) {
  91             if (failuresCount >= FAILURE_LIMIT) {
  92                 return;
  93             }
  94             previousInlineContext = new ArrayList<>();
  95             inlineContextMap = new WeakHashMap<>();
  96             DebugContext debug = graph.getDebug();
  97             try {
  98                 printer = printerSupplier.get(graph);



  99             } catch (IOException e) {
 100                 handleException(debug, e);
 101             }
 102         }
 103     }
 104 
 105     private int nextDumpId() {
 106         int depth = previousInlineContext.size();
 107         if (dumpIds.length < depth) {
 108             dumpIds = Arrays.copyOf(dumpIds, depth);
 109         }
 110         return dumpIds[depth - 1]++;
 111     }
 112 
 113     @Override
 114     @SuppressWarnings("try")
 115     public void dump(DebugContext debug, Object object, final String format, Object... arguments) {
 116         OptionValues options = debug.getOptions();
 117         if (object instanceof Graph && DebugOptions.PrintGraph.getValue(options)) {
 118             final Graph graph = (Graph) object;
 119             ensureInitialized(graph);
 120             if (printer == null) {
 121                 return;
 122             }

 123 
 124             // Get all current JavaMethod instances in the context.
 125             List<String> inlineContext = getInlineContext(graph);
 126 
 127             if (inlineContext != previousInlineContext) {
 128                 Map<Object, Object> properties = new HashMap<>();
 129                 properties.put("graph", graph.toString());
 130                 addCompilationId(properties, graph);

 131                 if (inlineContext.equals(previousInlineContext)) {
 132                     /*
 133                      * two different graphs have the same inline context, so make sure they appear
 134                      * in different folders by closing and reopening the top scope.
 135                      */
 136                     int inlineDepth = previousInlineContext.size() - 1;
 137                     closeScope(debug, inlineDepth);
 138                     openScope(debug, inlineContext.get(inlineDepth), inlineDepth, properties);
 139                 } else {
 140                     // Check for method scopes that must be closed since the previous dump.
 141                     for (int i = 0; i < previousInlineContext.size(); ++i) {
 142                         if (i >= inlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
 143                             for (int inlineDepth = previousInlineContext.size() - 1; inlineDepth >= i; --inlineDepth) {
 144                                 closeScope(debug, inlineDepth);
 145                             }
 146                             break;
 147                         }
 148                     }
 149                     // Check for method scopes that must be opened since the previous dump.
 150                     for (int i = 0; i < inlineContext.size(); ++i) {
 151                         if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
 152                             for (int inlineDepth = i; inlineDepth < inlineContext.size(); ++inlineDepth) {
 153                                 openScope(debug, inlineContext.get(inlineDepth), inlineDepth, inlineDepth == inlineContext.size() - 1 ? properties : null);
 154                             }
 155                             break;
 156                         }
 157                     }
 158                 }
 159             }
 160 
 161             // Save inline context for next dump.
 162             previousInlineContext = inlineContext;
 163 
 164             try (DebugContext.Scope s = debug.sandbox("PrintingGraph", null)) {
 165                 // Finally, output the graph.
 166                 Map<Object, Object> properties = new HashMap<>();
 167                 properties.put("graph", graph.toString());
 168                 properties.put("scope", debug.getCurrentScopeName());
 169                 if (graph instanceof StructuredGraph) {
 170                     properties.put("compilationIdentifier", ((StructuredGraph) graph).compilationId());
 171                     try {
 172                         int size = NodeCostUtil.computeGraphSize((StructuredGraph) graph);
 173                         properties.put("node-cost graph size", size);
 174                     } catch (Throwable t) {
 175                         properties.put("node-cost-exception", t.getMessage());
 176                     }
 177                 }
 178                 printer.print(debug, graph, properties, nextDumpId(), format, arguments);

 179             } catch (IOException e) {
 180                 handleException(debug, e);
 181             } catch (Throwable e) {
 182                 throw debug.handle(e);
 183             }
 184         }
 185     }
 186 
 187     void handleException(DebugContext debug, IOException e) {
 188         if (debug != null && DebugOptions.DumpingErrorsAreFatal.getValue(debug.getOptions())) {
 189             throw new GraalError(e);
 190         }
 191         if (e instanceof ClosedByInterruptException) {
 192             /*
 193              * The current dumping was aborted by an interrupt so treat this as a transient failure.
 194              */
 195             failuresCount = 0;
 196         } else {
 197             failuresCount++;
 198         }
 199         printer = null;

 200         e.printStackTrace(TTY.out);
 201         if (failuresCount > FAILURE_LIMIT) {
 202             TTY.println("Too many failures with dumping. Disabling dump in thread " + Thread.currentThread());


 203         }
 204     }
 205 
 206     private static void addCompilationId(Map<Object, Object> properties, final Graph graph) {
 207         if (graph instanceof StructuredGraph) {
 208             properties.put("compilationId", ((StructuredGraph) graph).compilationId());
 209         }
 210     }
 211 
















 212     private List<String> getInlineContext(Graph graph) {
 213         List<String> result = inlineContextMap.get(graph);
 214         if (result == null) {
 215             result = new ArrayList<>();
 216             Object lastMethodOrGraph = null;
 217             boolean graphSeen = false;
 218             DebugContext debug = graph.getDebug();
 219             for (Object o : debug.context()) {
 220                 if (o == graph) {
 221                     graphSeen = true;
 222                 }
 223 
 224                 if (o instanceof DebugDumpScope) {
 225                     DebugDumpScope debugDumpScope = (DebugDumpScope) o;
 226                     if (debugDumpScope.decorator && !result.isEmpty()) {
 227                         result.set(result.size() - 1, debugDumpScope.name + ":" + result.get(result.size() - 1));
 228                     } else {
 229                         result.add(debugDumpScope.name);
 230                     }
 231                 } else {
 232                     addMethodContext(result, o, lastMethodOrGraph);
 233                 }
 234                 if (o instanceof JavaMethod || o instanceof Graph) {
 235                     lastMethodOrGraph = o;
 236                 }
 237             }
 238 
 239             if (result.isEmpty()) {


 264             /*
 265              * Include the current method in the context if there was no previous JavaMethod or
 266              * JavaMethodContext or if the method is different or if the method is the same but it
 267              * comes from two different graphs. This ensures that recursive call patterns are
 268              * handled properly.
 269              */
 270             if (lastMethodOrGraph == null || asJavaMethod(lastMethodOrGraph) == null || !asJavaMethod(lastMethodOrGraph).equals(method) ||
 271                             (lastMethodOrGraph != o && lastMethodOrGraph instanceof Graph && o instanceof Graph)) {
 272                 result.add(method.format("%H.%n(%p)"));
 273             } else {
 274                 /*
 275                  * This prevents multiple adjacent method context objects for the same method from
 276                  * resulting in multiple IGV tree levels. This works on the assumption that real
 277                  * inlining debug scopes will have a graph context object between the inliner and
 278                  * inlinee context objects.
 279                  */
 280             }
 281         }
 282     }
 283 
 284     private void openScope(DebugContext debug, String name, int inlineDepth, Map<Object, Object> properties) {
 285         try {
 286             Map<Object, Object> props = properties;
 287             if (inlineDepth == 0) {
 288                 /* Include some VM specific properties at the root. */
 289                 if (props == null) {
 290                     props = new HashMap<>();
 291                 }
 292                 props.put("jvmArguments", jvmArguments);
 293                 if (sunJavaCommand != null) {
 294                     props.put("sun.java.command", sunJavaCommand);
 295                 }
 296                 props.put("date", new Date().toString());
 297             }
 298             printer.beginGroup(debug, name, name, debug.contextLookup(ResolvedJavaMethod.class), -1, props);
 299         } catch (IOException e) {
 300             handleException(debug, e);
 301         }
 302     }
 303 
 304     private void closeScope(DebugContext debug, int inlineDepth) {
 305         dumpIds[inlineDepth] = 0;
 306         try {
 307             if (printer != null) {
 308                 printer.endGroup();
 309             }
 310         } catch (IOException e) {
 311             handleException(debug, e);
 312         }
 313     }
 314 
 315     @Override
 316     public void close() {
 317         if (previousInlineContext != null) {
 318             for (int inlineDepth = 0; inlineDepth < previousInlineContext.size(); inlineDepth++) {
 319                 closeScope(null, inlineDepth);
 320             }
 321         }
 322         if (printer != null) {
 323             printer.close();
 324             printer = null;
 325         }
 326     }










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