@@ -53,8 +53,7 @@ public final class CallTreeInfo {
5353 private final Map <AnalysisMethod , RuntimeCompiledMethod > runtimeCompilations ;
5454 private Map <RuntimeCompilationCandidate , InvokeNode > runtimeCandidateMap ;
5555 private Map <AnalysisMethod , MethodNode > analysisMethodMap ;
56- private boolean callTreeInitialized = false ;
57- private boolean callTraceInitialized = false ;
56+ private boolean initialized = false ;
5857
5958 private CallTreeInfo (Map <AnalysisMethod , RuntimeCompiledMethod > runtimeCompilations ) {
6059 this .runtimeCompilations = runtimeCompilations ;
@@ -82,12 +81,7 @@ public static CallTreeInfo create(AnalysisUniverse aUniverse, Map<AnalysisMethod
8281 return new CallTreeInfo (runtimeCompilations );
8382 }
8483
85- private void initializeCallTraceInfo () {
86- if (callTraceInitialized ) {
87- return ;
88- }
89-
90- callTraceInitialized = true ;
84+ private void initializeCallerInfo () {
9185 analysisMethodMap = new HashMap <>();
9286 runtimeCandidateMap = new HashMap <>();
9387
@@ -131,22 +125,22 @@ private void initializeCallTraceInfo() {
131125 }
132126 }
133127
134- public void initializeCallTreeInfo (Set <AnalysisMethod > registeredRoots ) {
135- if (callTreeInitialized ) {
128+ public void initialize (Set <AnalysisMethod > registeredRoots ) {
129+ if (initialized ) {
136130 return ;
137131 }
138132
139- initializeCallTraceInfo ();
140- callTreeInitialized = true ;
133+ initializeCallerInfo ();
134+ initialized = true ;
141135
142136 // ensure invokeInfo calculated
143137
144138 Queue <MethodNode > worklist = new LinkedList <>();
145139 /*
146- * First initialize all nodes with no callers.
140+ * First initialize all nodes which are registered roots
147141 */
148142 for (var methodNode : analysisMethodMap .values ()) {
149- if (methodNode . getCallers (). isEmpty () || registeredRoots .contains (methodNode .method .getMultiMethod (ORIGINAL_METHOD ))) {
143+ if (registeredRoots .contains (methodNode .method .getMultiMethod (ORIGINAL_METHOD ))) {
150144 worklist .add (methodNode );
151145 methodNode .trace = new TraceInfo (0 , new BytecodePosition (null , methodNode .method , BytecodeFrame .UNKNOWN_BCI ), null );
152146 }
@@ -189,8 +183,8 @@ public void initializeCallTreeInfo(Set<AnalysisMethod> registeredRoots) {
189183 private static final String [] UNKNOWN_TRACE = new String []{"Unknown" };
190184 private static final String [] EMPTY_STRING = new String [0 ];
191185
192- public static String [] getCallTrace (CallTreeInfo callTreeInfo , AnalysisMethod method ) {
193- callTreeInfo .initializeCallTraceInfo ( );
186+ static String [] getCallTrace (CallTreeInfo callTreeInfo , AnalysisMethod method , Set < AnalysisMethod > registeredRuntimeCompilations ) {
187+ callTreeInfo .initialize ( registeredRuntimeCompilations );
194188 MethodNode methodNode = callTreeInfo .analysisMethodMap .get (method );
195189 if (methodNode == null ) {
196190 return UNKNOWN_TRACE ;
@@ -201,8 +195,8 @@ public static String[] getCallTrace(CallTreeInfo callTreeInfo, AnalysisMethod me
201195 return trace .toArray (EMPTY_STRING );
202196 }
203197
204- public static String [] getCallTrace (CallTreeInfo callTreeInfo , RuntimeCompilationCandidate candidate ) {
205- callTreeInfo .initializeCallTraceInfo ( );
198+ static String [] getCallTrace (CallTreeInfo callTreeInfo , RuntimeCompilationCandidate candidate , Set < AnalysisMethod > registeredRuntimeCompilations ) {
199+ callTreeInfo .initialize ( registeredRuntimeCompilations );
206200 InvokeNode invokeNode = callTreeInfo .runtimeCandidateMap .get (candidate );
207201 if (invokeNode == null ) {
208202 return UNKNOWN_TRACE ;
@@ -214,26 +208,48 @@ public static String[] getCallTrace(CallTreeInfo callTreeInfo, RuntimeCompilatio
214208 }
215209
216210 private static void findCallTraceHelper (ArrayList <String > trace , MethodNode first ) {
217- Set < MethodNode > covered = new HashSet <>();
218- MethodNode current = first ;
219- covered . add ( current );
220-
221- while ( current != null ) {
222- // find parent
223- MethodNode parent = null ;
224- for ( InvokeNode caller : current .getCallers ()) {
225- if (covered . add ( caller . method ) ) {
211+ if ( first . trace != null ) {
212+ /*
213+ * If there is a known trace from root, then we can return this
214+ */
215+ MethodNode current = first ;
216+ while ( current != null ) {
217+ MethodNode parent = null ;
218+ InvokeNode caller = current .trace . invokeParent ;
219+ if (caller != null ) {
226220 parent = caller .method ;
227221 trace .add (caller .position .toString ());
228- break ;
229222 }
223+ current = parent ;
224+ }
225+ trace .add ("[Root]" );
226+
227+ } else {
228+ /*
229+ * Otherwise we will walk an arbitrary caller until there is not a caller or we
230+ * encounter a cycle.
231+ */
232+ Set <MethodNode > covered = new HashSet <>();
233+ MethodNode current = first ;
234+ covered .add (current );
235+
236+ while (current != null ) {
237+ // find parent
238+ MethodNode parent = null ;
239+ for (InvokeNode caller : current .getCallers ()) {
240+ if (covered .add (caller .method )) {
241+ parent = caller .method ;
242+ trace .add (caller .position .toString ());
243+ break ;
244+ }
245+ }
246+ current = parent ;
230247 }
231- current = parent ;
232248 }
233249 }
234250
235251 public static void printCallTree (CallTreeInfo info , Set <AnalysisMethod > registeredRuntimeCompilations ) {
236- info .initializeCallTreeInfo (registeredRuntimeCompilations );
252+ info .initialize (registeredRuntimeCompilations );
237253
238254 System .out .println ("depth;method;invoke position" );
239255 for (MethodNode methodNode : info .analysisMethodMap .values ()) {
@@ -255,7 +271,7 @@ private static void printCallTreeNode(MethodNode node) {
255271 }
256272
257273 public static void printDeepestPath (CallTreeInfo info , Set <AnalysisMethod > registeredRuntimeCompilations ) {
258- info .initializeCallTreeInfo (registeredRuntimeCompilations );
274+ info .initialize (registeredRuntimeCompilations );
259275
260276 Optional <MethodNode > deepestNode = info .analysisMethodMap .values ().stream ().max (Comparator .comparingInt (t -> t .trace == null ? -1 : t .trace .level ));
261277
0 commit comments