diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CallTreePrinter.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CallTreePrinter.java index a4b3a12e2648..8f0c4d7ed3a6 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CallTreePrinter.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CallTreePrinter.java @@ -31,7 +31,12 @@ import static com.oracle.graal.pointsto.reports.ReportUtils.invokeComparator; import static com.oracle.graal.pointsto.reports.ReportUtils.methodComparator; +import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; @@ -46,6 +51,7 @@ import java.util.Objects; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -333,26 +339,33 @@ private static void printCsvFiles(Map methodToNode, walkNodes(node, directEdges, virtualEdges, overridenByEdges, virtualNodes, nonVirtualNodes, virtualNodeId); } - ReportUtils.report("call tree for vm entry point", reportsPath, "csv_call_tree_vm_" + reportName, "csv", - CallTreePrinter::printVMEntryPoint); - - ReportUtils.report("call tree for methods", reportsPath, "csv_call_tree_methods_" + reportName, "csv", - writer -> printMethodNodes(methodToNode.values(), writer)); - - ReportUtils.report("call tree for virtual methods", reportsPath, "csv_call_tree_virtual_methods_" + reportName, "csv", - writer -> printVirtualNodes(virtualNodes, writer)); - - ReportUtils.report("call tree for entry points", reportsPath, "csv_call_tree_entry_points_" + reportName, "csv", - writer -> printEntryPointIds(entryPointIds, writer)); - - ReportUtils.report("call tree for direct edges", reportsPath, "csv_call_tree_direct_edges_" + reportName, "csv", - writer -> printBciEdges(directEdges, writer)); - - ReportUtils.report("call tree for overriden by edges", reportsPath, "csv_call_tree_override_by_edges_" + reportName, "csv", - writer -> printNonBciEdges(overridenByEdges, writer)); + toCsvFile("call tree for vm entry point", reportsPath, "csv_call_tree_vm", reportName, CallTreePrinter::printVMEntryPoint); + toCsvFile("call tree for methods", reportsPath, "csv_call_tree_methods", reportName, writer -> printMethodNodes(methodToNode.values(), writer)); + toCsvFile("call tree for virtual methods", reportsPath, "csv_call_tree_virtual_methods", reportName, writer -> printVirtualNodes(virtualNodes, writer)); + toCsvFile("call tree for entry points", reportsPath, "csv_call_tree_entry_points", reportName, writer -> printEntryPointIds(entryPointIds, writer)); + toCsvFile("call tree for direct edges", reportsPath, "csv_call_tree_direct_edges", reportName, writer -> printBciEdges(directEdges, writer)); + toCsvFile("call tree for overriden by edges", reportsPath, "csv_call_tree_override_by_edges", reportName, writer -> printNonBciEdges(overridenByEdges, writer)); + toCsvFile("call tree for virtual edges", reportsPath, "csv_call_tree_virtual_edges", reportName, writer -> printBciEdges(virtualEdges, writer)); + } + + private static void toCsvFile(String description, String reportsPath, String prefix, String reportName, Consumer reporter) { + final String name = prefix + "_" + reportName; + final String csvFile = ReportUtils.report(description, reportsPath, name, "csv", reporter); + final Path csvLink = Paths.get(reportsPath).resolve(prefix + ".csv"); + + if (Files.exists(csvLink, LinkOption.NOFOLLOW_LINKS)) { + try { + Files.delete(csvLink); + } catch (IOException e) { + // Ignore + } + } - ReportUtils.report("call tree for virtual edges", reportsPath, "csv_call_tree_virtual_edges_" + reportName, "csv", - writer -> printBciEdges(virtualEdges, writer)); + try { + Files.createSymbolicLink(csvLink, Paths.get(csvFile)); + } catch (IOException e) { + throw new RuntimeException(e); + } } private static void printVMEntryPoint(PrintWriter writer) { diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java index 8b743b0544a0..63e4a8218dfa 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/ReportUtils.java @@ -75,10 +75,11 @@ public class ReportUtils { * @param extension the extension of the report * @param reporter a consumer that writes to a PrintWriter */ - public static void report(String description, String path, String name, String extension, Consumer reporter) { + public static String report(String description, String path, String name, String extension, Consumer reporter) { String fileName = timeStampedFileName(name, extension); Path reportDir = Paths.get(path); reportImpl(description, reportDir, fileName, reporter); + return fileName; } public static String timeStampedFileName(String name, String extension) {