Skip to content

Commit 4f44eed

Browse files
committed
Extend PrintAnalysisCallTree option
PrintAnalysisCallTree option accept a list of methods to print the call tree of them, or an empty string to print all call trees.
1 parent 05ce413 commit 4f44eed

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/AnalysisReportsOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class AnalysisReportsOptions {
3636
public static final OptionKey<String> AnalysisStatisticsFile = new OptionKey<>(null);
3737

3838
@Option(help = "Print analysis call tree, a breadth-first tree reduction of the call graph.")//
39-
public static final OptionKey<Boolean> PrintAnalysisCallTree = new OptionKey<>(false);
39+
public static final OptionKey<String> PrintAnalysisCallTree = new OptionKey<>(null);
4040

4141
@Option(help = "Print image object hierarchy.")//
4242
public static final OptionKey<Boolean> PrintImageObjectTree = new OptionKey<>(false);

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/reports/CallTreePrinter.java

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,17 @@
5454

5555
public final class CallTreePrinter {
5656

57-
public static void print(BigBang bigbang, String path, String reportName) {
57+
private static Set<String> printMethods = new HashSet<>();
58+
private static Set<Integer> printedID = new HashSet<>();
59+
private static boolean printAll = false;
60+
61+
public static void print(BigBang bigbang, String printCallTreeMethods, String path, String reportName) {
5862
CallTreePrinter printer = new CallTreePrinter(bigbang);
5963
printer.buildCallTree();
60-
64+
Arrays.stream(printCallTreeMethods.split(",")).forEach(printMethods::add);
65+
if (printCallTreeMethods.length() == 0) {
66+
printAll = true;
67+
}
6168
ReportUtils.report("call tree", path + File.separatorChar + "reports", "call_tree_" + reportName, "txt",
6269
writer -> printer.printMethods(writer));
6370
ReportUtils.report("list of used methods", path + File.separatorChar + "reports", "used_methods_" + reportName, "txt",
@@ -222,40 +229,58 @@ private void printMethods(PrintWriter out) {
222229
while (iterator.hasNext()) {
223230
MethodNode node = iterator.next();
224231
boolean lastEntryPoint = !iterator.hasNext();
225-
out.format("%s%s %s %n", lastEntryPoint ? LAST_CHILD : CHILD, "entry", node.format());
226-
printCallTreeNode(out, lastEntryPoint ? EMPTY_INDENT : CONNECTING_INDENT, node);
232+
printCallTreeNode(out, lastEntryPoint ? EMPTY_INDENT : CONNECTING_INDENT, node, false, lastEntryPoint ? LAST_CHILD : CHILD);
227233
}
228234
out.println();
229235
}
230236

231-
private static void printCallTreeNode(PrintWriter out, String prefix, MethodNode node) {
237+
private static void printCallTreeNode(PrintWriter out, String prefix, MethodNode node, boolean shouldPrint, String beginning) {
238+
boolean print = shouldPrint;
239+
if (!shouldPrint) {
240+
String methodName = node.method.getQualifiedName();
241+
if (printAll || printMethods.remove(methodName)) {
242+
print = true;
243+
out.format("%s%s %s %n", beginning, "entry", node.format());
244+
}
245+
}
232246

233247
for (int invokeIdx = 0; invokeIdx < node.invokes.size(); invokeIdx++) {
234248
InvokeNode invoke = node.invokes.get(invokeIdx);
235249
boolean lastInvoke = invokeIdx == node.invokes.size() - 1;
236250
if (invoke.isDirectInvoke) {
237251
if (invoke.callees.size() > 0) {
238252
Node calleeNode = invoke.callees.get(0);
239-
out.format("%s%s%s %s @bci=%s %n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
240-
"directly calls", calleeNode.format(), invoke.formatLocation());
241-
if (calleeNode instanceof MethodNode) {
242-
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode);
253+
boolean isNative = invoke.targetMethod.wrapped.getClass().getName().equals("com.oracle.svm.jni.hosted.JNINativeCallWrapperMethod");
254+
if (print) {
255+
if (calleeNode instanceof MethodNodeReference && printedID.add(((MethodNodeReference) calleeNode).methodNode.id)) {
256+
calleeNode = ((MethodNodeReference) calleeNode).methodNode;
257+
}
258+
out.format("%s%s%s %s @bci=%s %s %n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
259+
"directly calls", calleeNode.format(), invoke.formatLocation(), isNative ? "(Native Method)" : "");
260+
}
261+
if (!isNative && calleeNode instanceof MethodNode) {
262+
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode, print, null);
243263
}
244264
}
245265
} else {
246-
out.format("%s%s%s %s @bci=%s%n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
247-
"virtually calls", invoke.formatTarget(), invoke.formatLocation());
266+
if (print) {
267+
out.format("%s%s%s %s @bci=%s%n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
268+
"virtually calls", invoke.formatTarget(), invoke.formatLocation());
269+
}
248270
for (int calleeIdx = 0; calleeIdx < invoke.callees.size(); calleeIdx++) {
249271
boolean lastCallee = calleeIdx == invoke.callees.size() - 1;
250272
Node calleeNode = invoke.callees.get(calleeIdx);
251-
out.format("%s%s%s %s %n", prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (lastCallee ? LAST_CHILD : CHILD),
252-
"is overridden by", calleeNode.format());
273+
if (print) {
274+
out.format("%s%s%s %s %n", prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (lastCallee ? LAST_CHILD : CHILD),
275+
"is overridden by", calleeNode.format());
276+
}
253277
if (calleeNode instanceof MethodNode) {
254-
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT) + (lastCallee ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode);
278+
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT) + (lastCallee ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode, print, null);
255279
}
256280
}
257281
}
258282
}
283+
259284
}
260285

261286
private void printUsedMethods(PrintWriter out) {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,8 @@ private boolean runPointsToAnalysis(String imageName, OptionValues options, Debu
811811
StatisticsPrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
812812
}
813813

814-
if (AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options)) {
815-
CallTreePrinter.print(bigbang, SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
814+
if (AnalysisReportsOptions.PrintAnalysisCallTree.hasBeenSet(options)) {
815+
CallTreePrinter.print(bigbang, AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options), SubstrateOptions.Path.getValue(), ReportUtils.extractImageName(imageName));
816816
}
817817

818818
if (AnalysisReportsOptions.PrintImageObjectTree.getValue(options)) {

0 commit comments

Comments
 (0)