Skip to content

Commit d986983

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 42c83e1 commit d986983

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-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: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,17 @@
5252
import jdk.vm.ci.meta.ResolvedJavaMethod;
5353

5454
public final class CallTreePrinter {
55+
private static Set<String> printMethods = new HashSet<>();
56+
private static Set<Integer> printedID = new HashSet<>();
57+
private static boolean printAll = false;
5558

56-
public static void print(BigBang bigbang, String reportsPath, String reportName) {
59+
public static void print(BigBang bigbang, String printCallTreeMethods, String reportsPath, String reportName) {
5760
CallTreePrinter printer = new CallTreePrinter(bigbang);
5861
printer.buildCallTree();
59-
62+
Arrays.stream(printCallTreeMethods.split(",")).forEach(printMethods::add);
63+
if (printCallTreeMethods.length() == 0) {
64+
printAll = true;
65+
}
6066
ReportUtils.report("call tree", reportsPath, "call_tree_" + reportName, "txt",
6167
printer::printMethods);
6268
ReportUtils.report("list of used methods", reportsPath, "used_methods_" + reportName, "txt",
@@ -221,40 +227,64 @@ private void printMethods(PrintWriter out) {
221227
while (iterator.hasNext()) {
222228
MethodNode node = iterator.next();
223229
boolean lastEntryPoint = !iterator.hasNext();
224-
out.format("%s%s %s %n", lastEntryPoint ? LAST_CHILD : CHILD, "entry", node.format());
225-
printCallTreeNode(out, lastEntryPoint ? EMPTY_INDENT : CONNECTING_INDENT, node);
230+
printCallTreeNode(out, lastEntryPoint ? EMPTY_INDENT : CONNECTING_INDENT, node, false, lastEntryPoint ? LAST_CHILD : CHILD);
226231
}
227232
out.println();
228233
}
229234

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

232245
for (int invokeIdx = 0; invokeIdx < node.invokes.size(); invokeIdx++) {
233246
InvokeNode invoke = node.invokes.get(invokeIdx);
234247
boolean lastInvoke = invokeIdx == node.invokes.size() - 1;
235248
if (invoke.isDirectInvoke) {
236249
if (invoke.callees.size() > 0) {
237250
Node calleeNode = invoke.callees.get(0);
238-
out.format("%s%s%s %s @bci=%s %n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
239-
"directly calls", calleeNode.format(), invoke.formatLocation());
240-
if (calleeNode instanceof MethodNode) {
241-
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode);
251+
boolean isNative = invoke.targetMethod.wrapped.getClass().getName().equals("com.oracle.svm.jni.hosted.JNINativeCallWrapperMethod");
252+
if (print) {
253+
calleeNode = extendNodeReference(calleeNode);
254+
out.format("%s%s%s %s @bci=%s %s %n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
255+
"directly calls", calleeNode.format(), invoke.formatLocation(), isNative ? "(Native Method)" : "");
256+
}
257+
if (!isNative && calleeNode instanceof MethodNode) {
258+
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode, print, beginning);
242259
}
243260
}
244261
} else {
245-
out.format("%s%s%s %s @bci=%s%n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
246-
"virtually calls", invoke.formatTarget(), invoke.formatLocation());
262+
if (print) {
263+
out.format("%s%s%s %s @bci=%s%n", prefix, (lastInvoke ? LAST_CHILD : CHILD),
264+
"virtually calls", invoke.formatTarget(), invoke.formatLocation());
265+
}
247266
for (int calleeIdx = 0; calleeIdx < invoke.callees.size(); calleeIdx++) {
248267
boolean lastCallee = calleeIdx == invoke.callees.size() - 1;
249268
Node calleeNode = invoke.callees.get(calleeIdx);
250-
out.format("%s%s%s %s %n", prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (lastCallee ? LAST_CHILD : CHILD),
251-
"is overridden by", calleeNode.format());
269+
if (print) {
270+
calleeNode = extendNodeReference(calleeNode);
271+
out.format("%s%s%s %s %n", prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT), (lastCallee ? LAST_CHILD : CHILD),
272+
"is overridden by", calleeNode.format());
273+
}
252274
if (calleeNode instanceof MethodNode) {
253-
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT) + (lastCallee ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode);
275+
printCallTreeNode(out, prefix + (lastInvoke ? EMPTY_INDENT : CONNECTING_INDENT) + (lastCallee ? EMPTY_INDENT : CONNECTING_INDENT), (MethodNode) calleeNode, print, beginning);
254276
}
255277
}
256278
}
257279
}
280+
281+
}
282+
283+
private static Node extendNodeReference(Node calleeNode) {
284+
if (calleeNode instanceof MethodNodeReference && printedID.add(((MethodNodeReference) calleeNode).methodNode.id)) {
285+
calleeNode = ((MethodNodeReference) calleeNode).methodNode;
286+
}
287+
return calleeNode;
258288
}
259289

260290
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
@@ -776,8 +776,8 @@ private boolean runPointsToAnalysis(String imageName, OptionValues options, Debu
776776
StatisticsPrinter.print(bigbang, SubstrateOptions.reportsPath(), ReportUtils.extractImageName(imageName));
777777
}
778778

779-
if (AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options)) {
780-
CallTreePrinter.print(bigbang, SubstrateOptions.reportsPath(), ReportUtils.extractImageName(imageName));
779+
if (AnalysisReportsOptions.PrintAnalysisCallTree.hasBeenSet(options)) {
780+
CallTreePrinter.print(bigbang, AnalysisReportsOptions.PrintAnalysisCallTree.getValue(options), SubstrateOptions.reportsPath(), ReportUtils.extractImageName(imageName));
781781
}
782782

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

0 commit comments

Comments
 (0)