Accrue Pointer Analysis Exercise
ExtensionInfo that allows the CArray
language extension to be used with the Accrue framework.
Implement a pointer analysis
CContext and abstract heap objects are represented by
implementations of interface HContext.
initialContextImpl, which provides the initialCContextfor themainmethod.mergeImpl(CallSiteNode callSite, HContext receiver, CContext callerContext), which returns aCContextsuitable for the callee at call sitecallSite, where the caller is being analyzed with contextcallerContext, and the receiver of the method call is denoted by the abstract objectreceiver.recordImpl(CContext context, AllocSiteNode alloc), which returns aHContextsuitable for the object created at allocation sitealloc, occurring in contextcontext.
HeapAbstractionFactory is the base class of
different Accrue pointer analyses. We will create a context
sensitive pointer analysis in which contexts are abstractions of the
call stack. Specifically, a context is a stack of
ProcedureInstances. An abstract object is a pair of a
context and an allocation site.First download and install Accrue. (See here for further instructions.)
Create a package
accrue.tutorial.pointer.Create a class
ProcedureStackthat encapsulates a stack ofProcedureInstances. This class will represent our code contexts, so it should implement the interfaceaccrue.analysis.pointer.CContext.You can hard-code the
ProcedureStackto represent stacks of some fixed depth (e.g., 2). We suggest you implement a methodProcedureStack push(ProcedureInstance)which pushes aProcedureInstanceon to the top of the stack, and truncates the stack to the maximum depth. In the Polyglot style, this method should be pure (i.e., it does not modify the state of the receiver object, but returns a newProcedureStack).Note: you need to implement methods
int hashCode()andboolean equalsSemantic(CContext). You do not need to implementboolean equals(Object), as the Accrue pointer analyses use memoization forCContexts andHContexts, and rely on theequals(Object)method giving pointer equality.Create a class
AllocationNamethat encapsulates a pair of aProcedureStackand anAllocSiteNode. This class will represent our abstract heap objects, so it should implement the interfaceaccrue.analysis.pointer.HContext.Note: you again need to implement methods
int hashCode()andboolean equalsSemantic(HContext), but do not overrideboolean equals(Object).Create a class
ContextSensitivein the packageaccrue.tutorial.pointerthat extendsaccrue.analysis.pointer.analyses.HeapAbstractionFactory. Provide appropriate implementations of the methodsinitialContextImpl,mergeImplandrecordImpl.That is:
initialContextImplshould return aProcedureStackwith an empty stack of procedures. MethodmergeImplshould push the callee'sProcedureInstance(which can be gotten with the codecallSite.callee()) onto theProcedureStackof the caller. Finally, methodrecordImplshould return anAllocationNamefor the pair of the code context and the allocation site.You can now try running your pointer analysis on Java programs, by using the following code:
$ACCRUE/bin/accruec -classpath pathToYourTutorialClasses \ -heapabstraction accrue.tutorial.pointer.ContextSensitive C.java
You can find some example Java programs to run on in theexamplesdirectory of the Accrue tutorial code.
Create an AccrueExtensionInfo for CArray
ExtensionInfo that allows the CArray
language extension to be used with the Accrue framework.
Create a package
accrue.tutorial.carray.Create a class
accrue.tutorial.carray.CArrayAccrueExtInfowhich extendscarray.ExtensionInfoand implementsAccrueExtensionInfo. The interfaceAccrueExtensionInfocontains some method definitions useful for Accrue, such as methods to get the heap abstraction factory for the pointer analysis.Define the method
CArrayAccrueExtInfo.createNodeFactoryto add Accrue extension objects to newly created AST nodes. The following code snippet describes how to do this.@Override protected NodeFactory createNodeFactory() { return new CArrayNodeFactory_c(CArrayLang_c.instance, new CArrayExtFactory_c(new AnalysisExtFactory_c())); }Create class
AccrueCArrayOptionsand return a new instance of it from the methodCArrayAccrueExtInfo.createOptions. ClassAccrueCArrayOptionsshould extendCArrayOptionsand implementAccrueOptions. The code forAccrueCArrayOptionswill be very similar to the code found in the Accrue classAccrueJL5Options, as it uses anAccrueOptionsHelperobject to help with handling the Accrue command line options.Create class
AccrueCArraySchedulerand return a new instance of it from the methodCArrayAccrueExtInfo.createScheduler. ClassAccrueCArraySchedulershould extendCArraySchedulerand implementAccrueScheduler. To implementAccrueScheduler, this class needs to define methodhelper()which returns aAccrueSchedulerHelperobject. To enable us to easily add passes later, define classAccrueCArraySchedulerHelperwhich extendsAccrueSchedulerHelper, and put the following code in the body ofAccrueCArrayScheduler.final AccrueCArraySchedulerHelper helper; public AccrueCArrayScheduler(carray.ExtensionInfo extInfo) { super(extInfo); this.helper = new AccrueCArraySchedulerHelper(extInfo, this); } @Override public AccrueSchedulerHelper helper() { return this.helper; }- Insert the following boiler plate code into the class
CArrayAccrueExtInfo.private PointsToEngine pointsToEngine = null; @Override public PointsToEngine pointsToEngine() { if (pointsToEngine == null) { AccrueOptions opts = (AccrueOptions) this.getOptions(); pointsToEngine = opts.helper().createPointsToEngine(); } return pointsToEngine; } @Override public HeapAbstractionFactory heapAbstractionFactory() { return this.pointsToEngine().heapAbstractionFactory(); } @Override public StmtRegistrar createStmtRegistrar() { return new StmtRegistrar(this); } protected AnalysisSignatures analysisSignatures = null; @Override public AnalysisSignatures getAnalysisSignatures() { if (analysisSignatures == null) { analysisSignatures = createAnalysisSignatures(); } return analysisSignatures; } protected AnalysisSignatures createAnalysisSignatures() { return new AnalysisSignatures(); } @Override public boolean isOutputExtensionInfo() { return false; // we will do the analysis before the CArray code is translated } @Override public void setIsOutputExtensionInfo(boolean isOutputExtensionInfo) { } You can now try running your pointer analysis on CArray programs, by using the following code:
extclass=accrue.tutorial.carray.CArrayAccrueExtInfo $ACCRUE/bin/accruec \ -classpath pathToYourTutorialClasses -heapabstraction accrue.tutorial.pointer.ContextSensitive C.car
You can find some example CArray programs to run on in theexamplesdirectory of the Accrue tutorial code.