return mapHrnIdToAllocSite.get(id);
}
- public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
int paramIndex1,
int paramIndex2) {
checkAnalysisComplete();
return rg.mayReachSharedObjects(fm, paramIndex1, paramIndex2);
}
- public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
int paramIndex, AllocSite alloc) {
checkAnalysisComplete();
ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
return rg.mayReachSharedObjects(fm, paramIndex, alloc);
}
- public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
AllocSite alloc, int paramIndex) {
checkAnalysisComplete();
ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
return rg.mayReachSharedObjects(fm, paramIndex, alloc);
}
- public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> hasPotentialSharing(Descriptor taskOrMethod,
AllocSite alloc1, AllocSite alloc2) {
checkAnalysisComplete();
ReachGraph rg = mapDescriptorToCompleteReachGraph.get(taskOrMethod);
FlatMethod fm = state.getMethodFlat(td);
for (int i = 0; i < fm.numParameters(); ++i) {
+ // skip parameters with types that cannot reference
+ // into the heap
+ if( !shouldAnalysisTrack( fm.getParameter( i ).getType() ) ) {
+ continue;
+ }
+
// for the ith parameter check for aliases to all
// higher numbered parameters
for (int j = i + 1; j < fm.numParameters(); ++j) {
- common = createsPotentialAliases(td, i, j);
+
+ // skip parameters with types that cannot reference
+ // into the heap
+ if( !shouldAnalysisTrack( fm.getParameter( j ).getType() ) ) {
+ continue;
+ }
+
+
+ common = hasPotentialSharing(td, i, j);
if (!common.isEmpty()) {
foundSomeAlias = true;
if (!tabularOutput) {
Iterator allocItr = allocSites.iterator();
while (allocItr.hasNext()) {
AllocSite as = (AllocSite) allocItr.next();
- common = createsPotentialAliases(td, i, as);
+ common = hasPotentialSharing(td, i, as);
if (!common.isEmpty()) {
foundSomeAlias = true;
if (!tabularOutput) {
AllocSite as2 = (AllocSite) allocItr2.next();
if (!outerChecked.contains(as2)) {
- common = createsPotentialAliases(td, as1, as2);
+ common = hasPotentialSharing(td, as1, as2);
if (!common.isEmpty()) {
foundSomeAlias = true;
AllocSite as2 = (AllocSite) allocItr2.next();
if (!outerChecked.contains(as2)) {
- Set<HeapRegionNode> common = createsPotentialAliases(d,
+ Set<HeapRegionNode> common = hasPotentialSharing(d,
as1, as2);
if (!common.isEmpty()) {
Descriptor d = (Descriptor) me.getKey();
ReachGraph rg = (ReachGraph) me.getValue();
- try {
- rg.writeGraph( "COMPLETE"+d,
- true, // write labels (variables)
- true, // selectively hide intermediate temp vars
- true, // prune unreachable heap regions
- false, // hide subset reachability states
- true ); // hide edge taints
- } catch( IOException e ) {}
+ rg.writeGraph( "COMPLETE"+d,
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // hide subset reachability states
+ true ); // hide edge taints
}
}
FlatCall fc = (FlatCall) me2.getKey();
ReachGraph rg = (ReachGraph) me2.getValue();
- try {
- rg.writeGraph( "IHMPARTFOR"+d+"FROM"+fc,
- true, // write labels (variables)
- false, // selectively hide intermediate temp vars
- false, // prune unreachable heap regions
- false, // hide subset reachability states
- true ); // hide edge taints
- } catch( IOException e ) {}
+ rg.writeGraph( "IHMPARTFOR"+d+"FROM"+fc,
+ true, // write labels (variables)
+ false, // selectively hide intermediate temp vars
+ false, // prune unreachable heap regions
+ false, // hide subset reachability states
+ true ); // hide edge taints
}
}
}
}
Integer n = mapDescriptorToNumUpdates.get( d );
- try {
- rg.writeGraph( d+"COMPLETE"+String.format( "%05d", n ),
- true, // write labels (variables)
- true, // selectively hide intermediate temp vars
- true, // prune unreachable heap regions
- false, // hide subset reachability states
- true ); // hide edge taints
- } catch( IOException e ) {}
+ rg.writeGraph( d+"COMPLETE"+String.format( "%05d", n ),
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // hide subset reachability states
+ true ); // hide edge taints
mapDescriptorToNumUpdates.put( d, n + 1 );
}
// get successive captures of the analysis state
- boolean takeDebugSnapshots = false;
- String descSymbolDebug = "MDRunner";
- boolean stopAfterCapture = true;
+ boolean takeDebugSnapshots = true;
+ String descSymbolDebug = "calcGoodFeature";
+ boolean stopAfterCapture = false;
// increments every visit to debugSnapshot, don't fiddle with it
int debugCounter = 0;
int numStartCountReport = 0;
// the frequency of debugCounter values to print out, 0 no report
- int freqCountReport = 50;
+ int freqCountReport = 0;
// the debugCounter value at which to start taking snapshots
- int iterStartCapture = 350;
+ int iterStartCapture = 0;
// the number of snapshots to take
- int numIterToCapture = 400;
+ int numIterToCapture = 4000;
void debugSnapshot( ReachGraph rg, FlatNode fn, boolean in ) {
if( fn != null ) {
graphName = graphName + fn;
}
- try {
- rg.writeGraph( graphName,
- true, // write labels (variables)
- true, // selectively hide intermediate temp vars
- true, // prune unreachable heap regions
- false, // hide subset reachability states
- true );// hide edge taints
- } catch( Exception e ) {
- System.out.println( "Error writing debug capture." );
- System.exit( 0 );
- }
+ rg.writeGraph( graphName,
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // hide subset reachability states
+ true );// hide edge taints
}
if( debugCounter == iterStartCapture + numIterToCapture &&
);
oocEdgeExisting.setPreds( Canonical.join( oocEdgeExisting.getPreds(),
- reCaller.getPreds()
+ preds
)
);
if( writeDebugDOTs ) {
- try {
- rg.writeGraph( "calleeview",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ rg.writeGraph( "calleeview",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
return rg;
boolean writeDebugDOTs
) {
-
if( writeDebugDOTs ) {
- try {
- rgCallee.writeGraph( "callee",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
-
- writeGraph( "caller00In",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints,
- callerNodeIDsCopiedToCallee );
- } catch( IOException e ) {}
+ rgCallee.writeGraph( "callee",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
+
+ writeGraph( "caller00In",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints,
+ callerNodeIDsCopiedToCallee );
}
// 5. Global sweep it.
-
// 1. mark what callee elements have satisfied predicates
Hashtable<HeapRegionNode, ExistPredSet> calleeNodesSatisfied =
new Hashtable<HeapRegionNode, ExistPredSet>();
hrnCallee.getPreds().isSatisfiedBy( this,
callerNodeIDsCopiedToCallee
);
+
if( predsIfSatis != null ) {
calleeNodesSatisfied.put( hrnCallee, predsIfSatis );
} else {
HeapRegionNode hrnDstCaller = this.id2hrn.get( hrnCallee.getID() );
if( hrnDstCaller == null ) {
continue;
- }
+ }
Iterator<RefEdge> reDstItr = hrnDstCaller.iteratorToReferencers();
while( reDstItr.hasNext() ) {
RefSrcNode rsnCaller = reCaller.getSrc();
if( rsnCaller instanceof VariableNode ) {
+
// a variable node matches an OOC region with null type
if( hrnSrcCallee.getType() != null ) {
continue;
reCallee.getPreds().isSatisfiedBy( this,
callerNodeIDsCopiedToCallee
);
+
if( predsIfSatis != null ) {
calleeEdgesSatisfied.put( reCallee, predsIfSatis );
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller20BeforeWipe",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller20BeforeWipe",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller30BeforeAddingNodes",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller30BeforeAddingNodes",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller31BeforeAddingEdges",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller31BeforeAddingEdges",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
Set<RefSrcNode> oocCallers =
calleeEdges2oocCallerSrcMatches.get( reCallee );
- boolean oocEdges = false;
if( oocCallers == null ) {
// there are no out-of-context matches, so it's
// shouldn't this NEVER HAPPEN?
assert false;
}
+
rsnCallers.add( this.getVariableNodeFromTemp( tdArg ) );
- oocEdges = true;
} else {
// otherwise source is in context, one region
// that should NOT be translated to shadow nodes
assert !oocCallers.isEmpty();
rsnCallers.addAll( oocCallers );
- oocEdges = true;
}
// now make all caller edges we've identified from
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller35BeforeAssignReturnValue",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller35BeforeAssignReturnValue",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller38propagateReach",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller38propagateReach",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
// propagate callee reachability changes to the rest
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller40BeforeShadowMerge",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller40BeforeShadowMerge",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller45BeforeUnshadow",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller45BeforeUnshadow",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller50BeforeGlobalSweep",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller50BeforeGlobalSweep",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
if( writeDebugDOTs ) {
- try {
- writeGraph( "caller90AfterTransfer",
- resolveMethodDebugDOTwriteLabels,
- resolveMethodDebugDOTselectTemps,
- resolveMethodDebugDOTpruneGarbage,
- resolveMethodDebugDOThideSubsetReach,
- resolveMethodDebugDOThideEdgeTaints );
- } catch( IOException e ) {}
+ writeGraph( "caller90AfterTransfer",
+ resolveMethodDebugDOTwriteLabels,
+ resolveMethodDebugDOTselectTemps,
+ resolveMethodDebugDOTpruneGarbage,
+ resolveMethodDebugDOThideSubsetReach,
+ resolveMethodDebugDOThideEdgeTaints );
}
}
if( !id2hrn.containsKey( rtOld.getHrnID() ) ) {
System.out.println( "\nLooking for "+rtOld );
- try {
- writeGraph( "dbgz", true, true, true, true, true );
- } catch( IOException e ) {}
+ writeGraph( "dbgz" );
}
+ // the default signature for quick-and-dirty debugging
+ public void writeGraph( String graphName ) {
+ writeGraph( graphName,
+ true, // write labels
+ true, // label select
+ true, // prune garbage
+ true, // hide subset reachability
+ true, // hide edge taints
+ null // in-context boundary
+ );
+ }
+
public void writeGraph( String graphName,
boolean writeLabels,
boolean labelSelect,
boolean pruneGarbage,
boolean hideSubsetReachability,
boolean hideEdgeTaints
- ) throws java.io.IOException {
+ ) {
writeGraph( graphName,
writeLabels,
labelSelect,
boolean hideSubsetReachability,
boolean hideEdgeTaints,
Set<Integer> callerNodeIDsCopiedToCallee
- ) throws java.io.IOException {
+ ) {
- // remove all non-word characters from the graph name so
- // the filename and identifier in dot don't cause errors
- graphName = graphName.replaceAll( "[\\W]", "" );
-
- BufferedWriter bw =
- new BufferedWriter( new FileWriter( graphName+".dot" ) );
-
- bw.write( "digraph "+graphName+" {\n" );
+ try {
+ // remove all non-word characters from the graph name so
+ // the filename and identifier in dot don't cause errors
+ graphName = graphName.replaceAll( "[\\W]", "" );
+ BufferedWriter bw =
+ new BufferedWriter( new FileWriter( graphName+".dot" ) );
- // this is an optional step to form the callee-reachable
- // "cut-out" into a DOT cluster for visualization
- if( callerNodeIDsCopiedToCallee != null ) {
+ bw.write( "digraph "+graphName+" {\n" );
- bw.write( " subgraph cluster0 {\n" );
- bw.write( " color=blue;\n" );
-
- Iterator i = id2hrn.entrySet().iterator();
- while( i.hasNext() ) {
- Map.Entry me = (Map.Entry) i.next();
- HeapRegionNode hrn = (HeapRegionNode) me.getValue();
+
+ // this is an optional step to form the callee-reachable
+ // "cut-out" into a DOT cluster for visualization
+ if( callerNodeIDsCopiedToCallee != null ) {
- if( callerNodeIDsCopiedToCallee.contains( hrn.getID() ) ) {
- bw.write( " "+hrn.toString()+
- hrn.toStringDOT( hideSubsetReachability )+
- ";\n" );
+ bw.write( " subgraph cluster0 {\n" );
+ bw.write( " color=blue;\n" );
+
+ Iterator i = id2hrn.entrySet().iterator();
+ while( i.hasNext() ) {
+ Map.Entry me = (Map.Entry) i.next();
+ HeapRegionNode hrn = (HeapRegionNode) me.getValue();
+ if( callerNodeIDsCopiedToCallee.contains( hrn.getID() ) ) {
+ bw.write( " "+hrn.toString()+
+ hrn.toStringDOT( hideSubsetReachability )+
+ ";\n" );
+
+ }
}
+
+ bw.write( " }\n" );
}
-
- bw.write( " }\n" );
- }
-
-
- Set<HeapRegionNode> visited = new HashSet<HeapRegionNode>();
-
- // then visit every heap region node
- Iterator i = id2hrn.entrySet().iterator();
- while( i.hasNext() ) {
- Map.Entry me = (Map.Entry) i.next();
- HeapRegionNode hrn = (HeapRegionNode) me.getValue();
-
- // only visit nodes worth writing out--for instance
- // not every node at an allocation is referenced
- // (think of it as garbage-collected), etc.
- if( !pruneGarbage ||
- hrn.isOutOfContext()
- ) {
-
- if( !visited.contains( hrn ) ) {
- traverseHeapRegionNodes( hrn,
- bw,
- null,
- visited,
- hideSubsetReachability,
- hideEdgeTaints,
- callerNodeIDsCopiedToCallee );
- }
- }
- }
-
- bw.write( " graphTitle[label=\""+graphName+"\",shape=box];\n" );
-
-
- // then visit every label node, useful for debugging
- if( writeLabels ) {
- i = td2vn.entrySet().iterator();
+
+
+ Set<HeapRegionNode> visited = new HashSet<HeapRegionNode>();
+
+ // then visit every heap region node
+ Iterator i = id2hrn.entrySet().iterator();
while( i.hasNext() ) {
- Map.Entry me = (Map.Entry) i.next();
- VariableNode vn = (VariableNode) me.getValue();
-
- if( labelSelect ) {
- String labelStr = vn.getTempDescriptorString();
- if( labelStr.startsWith( "___temp" ) ||
- labelStr.startsWith( "___dst" ) ||
- labelStr.startsWith( "___srctmp" ) ||
- labelStr.startsWith( "___neverused" )
- ) {
- continue;
- }
- }
+ Map.Entry me = (Map.Entry) i.next();
+ HeapRegionNode hrn = (HeapRegionNode) me.getValue();
- Iterator<RefEdge> heapRegionsItr = vn.iteratorToReferencees();
- while( heapRegionsItr.hasNext() ) {
- RefEdge edge = heapRegionsItr.next();
- HeapRegionNode hrn = edge.getDst();
+ // only visit nodes worth writing out--for instance
+ // not every node at an allocation is referenced
+ // (think of it as garbage-collected), etc.
+ if( !pruneGarbage ||
+ hrn.isOutOfContext()
+ ) {
if( !visited.contains( hrn ) ) {
traverseHeapRegionNodes( hrn,
hideEdgeTaints,
callerNodeIDsCopiedToCallee );
}
+ }
+ }
+
+ bw.write( " graphTitle[label=\""+graphName+"\",shape=box];\n" );
+
+
+ // then visit every label node, useful for debugging
+ if( writeLabels ) {
+ i = td2vn.entrySet().iterator();
+ while( i.hasNext() ) {
+ Map.Entry me = (Map.Entry) i.next();
+ VariableNode vn = (VariableNode) me.getValue();
- bw.write( " "+vn.toString()+
- " -> "+hrn.toString()+
- edge.toStringDOT( hideSubsetReachability, "" )+
- ";\n" );
+ if( labelSelect ) {
+ String labelStr = vn.getTempDescriptorString();
+ if( labelStr.startsWith( "___temp" ) ||
+ labelStr.startsWith( "___dst" ) ||
+ labelStr.startsWith( "___srctmp" ) ||
+ labelStr.startsWith( "___neverused" )
+ ) {
+ continue;
+ }
+ }
+
+ Iterator<RefEdge> heapRegionsItr = vn.iteratorToReferencees();
+ while( heapRegionsItr.hasNext() ) {
+ RefEdge edge = heapRegionsItr.next();
+ HeapRegionNode hrn = edge.getDst();
+
+ if( !visited.contains( hrn ) ) {
+ traverseHeapRegionNodes( hrn,
+ bw,
+ null,
+ visited,
+ hideSubsetReachability,
+ hideEdgeTaints,
+ callerNodeIDsCopiedToCallee );
+ }
+
+ bw.write( " "+vn.toString()+
+ " -> "+hrn.toString()+
+ edge.toStringDOT( hideSubsetReachability, "" )+
+ ";\n" );
+ }
}
}
- }
- bw.write( "}\n" );
- bw.close();
+ bw.write( "}\n" );
+ bw.close();
+
+ } catch( IOException e ) {
+ throw new Error( "Error writing out DOT graph "+graphName );
+ }
}
protected void traverseHeapRegionNodes( HeapRegionNode hrn,
ReachTuple.ARITY_ONE,
false ); // ooc?
- ReachTuple h1star =
- ReachTuple.factory( hrn1.getID(),
- !hrn1.isSingleObject(),
- ReachTuple.ARITY_ZEROORMORE,
- false );
+ ReachTuple h1star = null;
+ if( !hrn1.isSingleObject() ) {
+ h1star =
+ ReachTuple.factory( hrn1.getID(),
+ !hrn1.isSingleObject(),
+ ReachTuple.ARITY_ZEROORMORE,
+ false );
+ }
ReachTuple h2 =
ReachTuple.factory( hrn2.getID(),
!hrn2.isSingleObject(),
ReachTuple.ARITY_ONE,
false );
-
- ReachTuple h2star =
- ReachTuple.factory( hrn2.getID(),
- !hrn2.isSingleObject(),
- ReachTuple.ARITY_ZEROORMORE,
- false );
+
+ ReachTuple h2star = null;
+ if( !hrn2.isSingleObject() ) {
+ h2star =
+ ReachTuple.factory( hrn2.getID(),
+ !hrn2.isSingleObject(),
+ ReachTuple.ARITY_ZEROORMORE,
+ false );
+ }
// then get the merged beta of all out-going edges from these heap
// regions
Canonical.unionORpreds( proofOfSharing,
beta1.getStatesWithBoth( h1, h2 )
);
- proofOfSharing =
- Canonical.unionORpreds( proofOfSharing,
- beta1.getStatesWithBoth( h1star, h2 )
- );
- proofOfSharing =
- Canonical.unionORpreds( proofOfSharing,
- beta1.getStatesWithBoth( h1, h2star )
- );
- proofOfSharing =
- Canonical.unionORpreds( proofOfSharing,
- beta1.getStatesWithBoth( h1star, h2star )
- );
-
proofOfSharing =
Canonical.unionORpreds( proofOfSharing,
beta2.getStatesWithBoth( h1, h2 )
);
+
+ if( !hrn1.isSingleObject() ) {
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta1.getStatesWithBoth( h1star, h2 )
+ );
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta2.getStatesWithBoth( h1star, h2 )
+ );
+ }
+
+ if( !hrn2.isSingleObject() ) {
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta1.getStatesWithBoth( h1, h2star )
+ );
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta2.getStatesWithBoth( h1, h2star )
+ );
+ }
+
+ if( !hrn1.isSingleObject() &&
+ !hrn2.isSingleObject()
+ ) {
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta1.getStatesWithBoth( h1star, h2star )
+ );
+ proofOfSharing =
+ Canonical.unionORpreds( proofOfSharing,
+ beta2.getStatesWithBoth( h1star, h2star )
+ );
+ }
+
+ Set<HeapRegionNode> common = new HashSet<HeapRegionNode>();
+ if( !proofOfSharing.isEmpty() ) {
+ common = findCommonReachableNodes( proofOfSharing );
+ if( !DISABLE_STRONG_UPDATES &&
+ !DISABLE_GLOBAL_SWEEP
+ ) {
+ assert !common.isEmpty();
+ }
+ }
+
+ return common;
+ }
+
+ // this version of the above method checks whether there is sharing
+ // among the objects in a summary node
+ public Set<HeapRegionNode> mayReachSharedObjects(HeapRegionNode hrn) {
+ assert hrn != null;
+ assert hrn.isNewSummary();
+ assert !hrn.isOutOfContext();
+ assert belongsToThis( hrn );
+
+ ReachTuple hstar =
+ ReachTuple.factory( hrn.getID(),
+ true, // multi
+ ReachTuple.ARITY_ZEROORMORE,
+ false ); // ooc
+
+ // then get the merged beta of all out-going edges from
+ // this heap region
+
+ ReachSet beta = ReachSet.factory();
+ Iterator<RefEdge> itrEdge = hrn.iteratorToReferencees();
+ while (itrEdge.hasNext()) {
+ RefEdge edge = itrEdge.next();
+ beta = Canonical.unionORpreds(beta, edge.getBeta());
+ }
+
+ ReachSet proofOfSharing = ReachSet.factory();
+
proofOfSharing =
Canonical.unionORpreds( proofOfSharing,
- beta2.getStatesWithBoth( h1star, h2 )
- );
- proofOfSharing =
- Canonical.unionORpreds( proofOfSharing,
- beta2.getStatesWithBoth( h1, h2star )
- );
- proofOfSharing =
- Canonical.unionORpreds( proofOfSharing,
- beta2.getStatesWithBoth( h1star, h2star )
+ beta.getStatesWithBoth( hstar, hstar )
);
Set<HeapRegionNode> common = new HashSet<HeapRegionNode>();
assert !common.isEmpty();
}
}
-
+
return common;
}
// get parameter's heap regions
TempDescriptor paramTemp1 = fm.getParameter(paramIndex1.intValue());
+ assert this.hasVariable( paramTemp1 );
VariableNode paramVar1 = getVariableNodeFromTemp(paramTemp1);
+
+
+ if( !(paramVar1.getNumReferencees() == 1) ) {
+ System.out.println( "\n fm="+fm+"\n param="+paramTemp1 );
+ writeGraph( "whatup" );
+ }
+
+
assert paramVar1.getNumReferencees() == 1;
RefEdge paramEdge1 = paramVar1.iteratorToReferencees().next();
HeapRegionNode hrnParam1 = paramEdge1.getDst();
TempDescriptor paramTemp2 = fm.getParameter(paramIndex2.intValue());
+ assert this.hasVariable( paramTemp2 );
VariableNode paramVar2 = getVariableNodeFromTemp(paramTemp2);
+
+ if( !(paramVar2.getNumReferencees() == 1) ) {
+ System.out.println( "\n fm="+fm+"\n param="+paramTemp2 );
+ writeGraph( "whatup" );
+ }
+
assert paramVar2.getNumReferencees() == 1;
RefEdge paramEdge2 = paramVar2.iteratorToReferencees().next();
HeapRegionNode hrnParam2 = paramEdge2.getDst();
// get parameter's heap regions
TempDescriptor paramTemp = fm.getParameter(paramIndex.intValue());
+ assert this.hasVariable( paramTemp );
VariableNode paramVar = getVariableNodeFromTemp(paramTemp);
assert paramVar.getNumReferencees() == 1;
RefEdge paramEdge = paramVar.iteratorToReferencees().next();
}
Set<HeapRegionNode> common = new HashSet<HeapRegionNode>();
- if(hrnSum1!=null && hrnSum2!=null){
+ if(hrnSum1!=null && hrnSum2!=null && hrnSum1!=hrnSum2){
common.addAll(mayReachSharedObjects(hrnSum1, hrnSum2));
}
+ if(hrnSum1!=null){
+ // ask if objects from this summary share among each other
+ common.addAll(mayReachSharedObjects(hrnSum1));
+ }
+
// check sum2 against alloc1 nodes
if(hrnSum2!=null){
for (int i = 0; i < as1.getAllocationDepth(); ++i) {
assert hrnI1 != null;
common.addAll(mayReachSharedObjects(hrnI1, hrnSum2));
}
+
+ // also ask if objects from this summary share among each other
+ common.addAll(mayReachSharedObjects(hrnSum2));
}
// check sum1 against alloc2 nodes
}
return common;
- }
-
+ }
}