/*
* Copyright (c) 2011, 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 org.graalvm.compiler.printer;
import static org.graalvm.compiler.debug.GraalDebugConfig.asJavaMethod;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.graalvm.compiler.debug.Debug;
import org.graalvm.compiler.debug.Debug.Scope;
import org.graalvm.compiler.debug.DebugDumpHandler;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.GraalDebugConfig.Options;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.nodes.StructuredGraph;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
//JaCoCo Exclude
/**
* Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation
* that can be inspected with the Ideal Graph Visualizer
* .
*/
public class GraphPrinterDumpHandler implements DebugDumpHandler {
private final GraphPrinterSupplier printerSupplier;
protected GraphPrinter printer;
private List previousInlineContext;
private int[] dumpIds = {};
private int failuresCount;
private Map> inlineContextMap;
private final String jvmArguments;
private final String sunJavaCommand;
@FunctionalInterface
public interface GraphPrinterSupplier {
GraphPrinter get() throws IOException;
}
/**
* Creates a new {@link GraphPrinterDumpHandler}.
*
* @param printerSupplier Supplier used to create the GraphPrinter. Should supply an optional or
* null in case of failure.
*/
public GraphPrinterDumpHandler(GraphPrinterSupplier printerSupplier) {
this.printerSupplier = printerSupplier;
/* Add the JVM and Java arguments to the graph properties to help identify it. */
this.jvmArguments = String.join(" ", ManagementFactory.getRuntimeMXBean().getInputArguments());
this.sunJavaCommand = System.getProperty("sun.java.command");
}
private void ensureInitialized() {
if (printer == null) {
if (failuresCount > 8) {
return;
}
previousInlineContext = new ArrayList<>();
inlineContextMap = new WeakHashMap<>();
try {
printer = printerSupplier.get();
} catch (IOException e) {
TTY.println(e.getMessage());
failuresCount++;
}
}
}
private int nextDumpId() {
int depth = previousInlineContext.size();
if (dumpIds.length < depth) {
dumpIds = Arrays.copyOf(dumpIds, depth);
}
return dumpIds[depth - 1]++;
}
@Override
@SuppressWarnings("try")
public void dump(Object object, final String message) {
if (object instanceof Graph && Options.PrintIdealGraph.getValue()) {
ensureInitialized();
if (printer == null) {
return;
}
final Graph graph = (Graph) object;
// Get all current JavaMethod instances in the context.
List inlineContext = getInlineContext(graph);
if (inlineContext != previousInlineContext) {
Map