OPAL-Regarding Finding Calledges of methods defined in Abstract Class using CHA algorithm

96 views Asked by At

Here is a question related to the algorithm of constructing the call graph for Java bytecode using CHA.

As there is no concrete method implementation for methods in abstract classes, adding a call edge to such methods might be a bit misleading. take junit-4.12.jar for instance. runFailed has been defined in junit.runner.BaseTestRunner which is an abstract class. Besides, there are calls to runFailed in method getTest which also defined in junit.runner.BaseTestRunner

While in "Assumption Hierarchy for a CHA Call Graph Construction Algorithm"(Jason&Atanas), it is said that

"given a call site x.m(), where the declared type of x is C, the possible runtime type of x must be a non-abstract subtype of C."

As far as i'm considered, without add a call edge(Calledge1) from junit.runner.BaseTestRunner getTest to junit.runner.BaseTestRunner runFailed, it is more reasonable to add a call edge(Calledge2) from junit.runner.BaseTestRunner getTest to junit/textui/TestRunner runFailed as TestRunner extends BaseTestRunner.

While after running test code to get the result of CallGraph.calledByStatistics(), only Calledge1 has been found. Calledge2 is missing.

Is there anybody can do me a favor to confirm this? Thank you in advance.

Regards,

Jiang

1

There are 1 answers

0
Jiang Zheng On BEST ANSWER

I found OPAL offers two views of call graph. The second one won't add a "library-call" edge into call edge.

In CallGraph.calledByStatistics()

The binding is between Callsite (PC) to caller.method for example: between “INVOKEVIRTUAL(junit.runner.BaseTestRunner{ void runFailed(java.lang.String) })” and junit/runner/BaseTestRunner.public junit.framework.Test getTest(java.lang.String)

In CallGraph.callsStatistics()

The binding is between subtype.method to caller.method for example: between "junit/textui/TestRunner.protected void runFailed(java.lang.String)” and “junit/runner/BaseTestRunner.public junit.framework.Test getTest(java.lang.String)”