BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile) );
+ bw.write("Conducting ownership analysis with allocation depth = "+allocationDepth);
+
// look through every task for potential aliases
Iterator taskItr = state.getTaskSymbolTable().getDescriptorsIterator();
while( taskItr.hasNext() ) {
TaskDescriptor td = (TaskDescriptor) taskItr.next();
bw.write("\n---------"+td+"--------\n");
- bw.flush();
HashSet<AllocationSite> allocSites = getFlaggedAllocationSitesReachableFromTask(td);
AllocationSite as = (AllocationSite) allocItr.next();
if( createsPotentialAliases(td, i, as) ) {
foundSomeAlias = true;
- bw.write("Potential alias between parameter "+i+" and "+as+".\n");
+ bw.write("Potential alias between parameter "+i+" and "+as.getFlatNew()+".\n");
}
}
}
if( !outerChecked.contains(as2) &&
createsPotentialAliases(td, as1, as2) ) {
foundSomeAlias = true;
- bw.write("Potential alias between "+as1+" and "+as2+".\n");
+ bw.write("Potential alias between "+as1.getFlatNew()+" and "+as2.getFlatNew()+".\n");
}
}
}
if( !foundSomeAlias ) {
- bw.write("Task "+td+" contains no aliases between flagged objects.\n");
+ bw.write("No aliases between flagged objects in Task "+td+".\n");
}
}
null,
false);
// for controlling DOT file output
- private boolean writeFinalGraphs;
- private boolean writeAllUpdates;
+ private boolean writeDOTs;
+ private boolean writeAllDOTs;
TypeUtil tu,
CallGraph callGraph,
int allocationDepth,
- boolean writeFinalGraphs,
- boolean writeAllUpdates) throws java.io.IOException {
+ boolean writeDOTs,
+ boolean writeAllDOTs,
+ String aliasFile) throws java.io.IOException {
- this.state = state;
- this.typeUtil = tu;
- this.callGraph = callGraph;
- this.allocationDepth = allocationDepth;
- this.writeFinalGraphs = writeFinalGraphs;
- this.writeAllUpdates = writeAllUpdates;
+ this.state = state;
+ this.typeUtil = tu;
+ this.callGraph = callGraph;
+ this.allocationDepth = allocationDepth;
+ this.writeDOTs = writeDOTs;
+ this.writeAllDOTs = writeAllDOTs;
descriptorsToAnalyze = new HashSet<Descriptor>();
mapDescriptorToAllocationSiteSet =
new Hashtable<Descriptor, HashSet<AllocationSite> >();
- if( writeAllUpdates ) {
+ if( writeAllDOTs ) {
mapDescriptorToNumUpdates = new Hashtable<Descriptor, Integer>();
}
// a method if the methods that it calls are updated
analyzeMethods();
- writeAllAliases("identifiedAliases.txt");
+ System.out.println("");
+
+ if( aliasFile != null ) {
+ writeAllAliases(aliasFile);
+ }
}
// called from the constructor to help initialize the set
OwnershipGraph og = analyzeFlatMethod(d, fm);
OwnershipGraph ogPrev = mapDescriptorToCompleteOwnershipGraph.get(d);
if( !og.equals(ogPrev) ) {
-
setGraphForDescriptor(d, og);
// only methods have dependents, tasks cannot
FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
flatNodesToVisit.remove(fn);
+ //System.out.println( " "+fn );
+
// perform this node's contributions to the ownership
// graph on a new copy, then compare it to the old graph
// at this node to see if anything was updated.
// start by merging all node's parents' graphs
for( int i = 0; i < fn.numPrev(); ++i ) {
- FlatNode pn = fn.getPrev(i);
- OwnershipGraph ogParent = getGraphFromFlatNode(pn);
- og.merge(ogParent);
+ FlatNode pn = fn.getPrev(i);
+ if( mapFlatNodeToOwnershipGraph.containsKey(pn) ) {
+ OwnershipGraph ogParent = mapFlatNodeToOwnershipGraph.get(pn);
+ og.merge(ogParent);
+ }
}
// apply the analysis of the flat node to the
returnNodesToCombineForCompleteOwnershipGraph,
og);
+
+ //debugSnapshot(og,fn);
+
+
+
// if the results of the new graph are different from
// the current graph at this node, replace the graph
// with the update and enqueue the children for
// processing
- OwnershipGraph ogPrev = getGraphFromFlatNode(fn);
-
+ OwnershipGraph ogPrev = mapFlatNodeToOwnershipGraph.get(fn);
if( !og.equals(ogPrev) ) {
- setGraphForFlatNode(fn, og);
+ mapFlatNodeToOwnershipGraph.put(fn, og);
for( int i = 0; i < fn.numNext(); i++ ) {
FlatNode nn = fn.getNext(i);
Iterator retItr = returnNodesToCombineForCompleteOwnershipGraph.iterator();
while( retItr.hasNext() ) {
FlatReturnNode frn = (FlatReturnNode) retItr.next();
- OwnershipGraph ogr = getGraphFromFlatNode(frn);
+ assert mapFlatNodeToOwnershipGraph.containsKey(frn);
+ OwnershipGraph ogr = mapFlatNodeToOwnershipGraph.get(frn);
completeGraph.merge(ogr);
- }
+ }
+
return completeGraph;
}
lhs = ffn.getDst();
rhs = ffn.getSrc();
fld = ffn.getField();
- if( !fld.getType().isPrimitive() ) {
+ if( !fld.getType().isImmutable() ) {
og.assignTempXEqualToTempYFieldF(lhs, rhs, fld);
}
break;
lhs = fsfn.getDst();
fld = fsfn.getField();
rhs = fsfn.getSrc();
- og.assignTempXFieldFEqualToTempY(lhs, fld, rhs);
+ if( !fld.getType().isImmutable() ) {
+ og.assignTempXFieldFEqualToTempY(lhs, fld, rhs);
+ }
break;
case FKind.FlatElementNode:
FlatElementNode fen = (FlatElementNode) fn;
lhs = fen.getDst();
rhs = fen.getSrc();
- if( !lhs.getType().isPrimitive() ) {
+ if( !lhs.getType().isImmutable() ) {
og.assignTempXEqualToTempYFieldF(lhs, rhs, fdElement);
}
break;
FlatSetElementNode fsen = (FlatSetElementNode) fn;
lhs = fsen.getDst();
rhs = fsen.getSrc();
- if( !rhs.getType().isPrimitive() ) {
+ if( !rhs.getType().isImmutable() ) {
og.assignTempXFieldFEqualToTempY(lhs, fdElement, rhs);
}
break;
case FKind.FlatNew:
FlatNew fnn = (FlatNew) fn;
lhs = fnn.getDst();
- AllocationSite as = getAllocationSiteFromFlatNewPRIVATE(fnn);
-
- og.assignTempEqualToNewAlloc(lhs, as);
+ if( !lhs.getType().isImmutable() ) {
+ AllocationSite as = getAllocationSiteFromFlatNewPRIVATE(fnn);
+ og.assignTempEqualToNewAlloc(lhs, as);
+ }
break;
case FKind.FlatCall:
}
}
- og = ogMergeOfAllPossibleCalleeResults;
+ og = ogMergeOfAllPossibleCalleeResults;
break;
case FKind.FlatReturnNode:
FlatReturnNode frn = (FlatReturnNode) fn;
rhs = frn.getReturnTemp();
-
- if( rhs != null ) {
+ if( rhs != null && !rhs.getType().isImmutable() ) {
og.assignReturnEqualToTemp(rhs);
}
-
setRetNodes.add(frn);
break;
}
}
+ // insert a call to debugSnapshot() somewhere in the analysis to get
+ // successive captures of the analysis state
+ int debugCounter = 0;
+ int numStartCountReport = 0;
+ int freqCountReport = 1000;
+ int iterStartCapture = 20000;
+ int numIterToCapture = 400;
+ void debugSnapshot( OwnershipGraph og, FlatNode fn ) {
+ ++debugCounter;
+ if( debugCounter > numStartCountReport &&
+ debugCounter % freqCountReport == 0 ) {
+ System.out.println( " @@@ debug counter = "+debugCounter );
+ }
+ if( debugCounter > iterStartCapture ) {
+ System.out.println( " @@@ capturing debug "+(debugCounter-iterStartCapture)+" @@@" );
+ String graphName = String.format("snap%04d",debugCounter-iterStartCapture);
+ if( fn != null ) {
+ graphName = graphName+fn;
+ }
+ try {
+ og.writeGraph( graphName, true, true, false, false, false );
+ } catch( Exception e ) {
+ System.out.println( "Error writing debug capture." );
+ System.exit( 0 );
+ }
+ }
+ if( debugCounter == iterStartCapture + numIterToCapture ) {
+ System.out.println( "Stopping analysis after debug captures." );
+ System.exit( 0 );
+ }
+ }
+
+
+
// this method should generate integers strictly greater than zero!
// special "shadow" regions are made from a heap region by negating
// the ID
// boolean labelSelect,
// boolean pruneGarbage,
// boolean writeReferencers
+ // boolean writeParamMappings
- if( writeFinalGraphs ) {
+ if( writeDOTs ) {
- if( !writeAllUpdates ) {
- og.writeGraph(d, true, true, true, false);
+ if( !writeAllDOTs ) {
+ og.writeGraph(d, true, true, true, false, false);
} else {
if( !mapDescriptorToNumUpdates.containsKey(d) ) {
mapDescriptorToNumUpdates.put(d, new Integer(0) );
}
Integer n = mapDescriptorToNumUpdates.get(d);
- og.writeGraph(d, n, true, true, true, false);
+ og.writeGraph(d, n, true, true, true, false, false);
mapDescriptorToNumUpdates.put(d, n + 1);
}
}
}
- private OwnershipGraph getGraphFromFlatNode(FlatNode fn) {
- if( !mapFlatNodeToOwnershipGraph.containsKey(fn) ) {
- mapFlatNodeToOwnershipGraph.put(fn, new OwnershipGraph(allocationDepth, typeUtil) );
- }
-
- return mapFlatNodeToOwnershipGraph.get(fn);
- }
-
- private void setGraphForFlatNode(FlatNode fn, OwnershipGraph og) {
- mapFlatNodeToOwnershipGraph.put(fn, og);
- }
-
-
// return just the allocation site associated with one FlatNew node
private AllocationSite getAllocationSiteFromFlatNewPRIVATE(FlatNew fn) {
if( !mapFlatNewToAllocationSite.containsKey(fn) ) {
- AllocationSite as = new AllocationSite(allocationDepth, fn.getType() );
+ AllocationSite as = new AllocationSite(allocationDepth, fn );
// the newest nodes are single objects
for( int i = 0; i < allocationDepth; ++i ) {