mapDescriptorToReachGraph =
new Hashtable<Descriptor, ReachGraph>();
- pm = new PointerMethod();
-
fc2enclosing = new Hashtable<FlatCall, Descriptor>();
}
ReachGraph.debugCallSiteVisitCounter
= 0; // count visits from 1, is incremented before first visit
+ pm = new PointerMethod();
+
if( state.DO_DEFINITE_REACH_ANALYSIS ) {
doDefiniteReachAnalysis = true;
- definiteReachAnalysis = new DefiniteReachAnalysis();
+ definiteReachAnalysis = new DefiniteReachAnalysis( pm );
}
FlatSESEEnterNode sese;
FlatSESEExitNode fsexn;
+ Set<EdgeKey> edgeKeysForLoad;
+ Set<EdgeKey> edgeKeysRemoved;
+ Set<EdgeKey> edgeKeysAdded;
+
//Stores the flatnode's reach graph at enter
ReachGraph rgOnEnter = new ReachGraph();
rgOnEnter.merge(rg);
fn2rgAtEnter.put(fn, rgOnEnter);
+
+ boolean didDefReachTransfer = false;
+
+
// use node type to decide what transfer function
// to apply to the reachability graph
params.add( fm.getParameter( i ) );
}
definiteReachAnalysis.methodEntry( fn, params );
+ didDefReachTransfer = true;
}
} break;
if( doDefiniteReachAnalysis ) {
definiteReachAnalysis.copy( fn, lhs, rhs );
+ didDefReachTransfer = true;
}
}
break;
if( doDefiniteReachAnalysis ) {
definiteReachAnalysis.copy( fn, lhs, rhs );
+ didDefReachTransfer = true;
}
break;
}
}
+ edgeKeysForLoad = null;
+ if( doDefiniteReachAnalysis ) {
+ edgeKeysForLoad = new HashSet<EdgeKey>();
+ }
+
if( shouldAnalysisTrack(fld.getType() ) ) {
// transfer func
- rg.assignTempXEqualToTempYFieldF(lhs, rhs, fld, fn);
+ rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld, fn, edgeKeysForLoad );
if( doDefiniteReachAnalysis ) {
- definiteReachAnalysis.load( fn, lhs, rhs, fld );
+ definiteReachAnalysis.load( fn, lhs, rhs, fld, edgeKeysForLoad );
+ didDefReachTransfer = true;
}
}
boolean strongUpdate = false;
+ edgeKeysRemoved = null;
+ edgeKeysAdded = null;
+ if( doDefiniteReachAnalysis ) {
+ edgeKeysRemoved = new HashSet<EdgeKey>();
+ edgeKeysAdded = new HashSet<EdgeKey>();
+ }
+
// before transfer func, possibly inject
// stall-site taints
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
if( shouldAnalysisTrack(fld.getType() ) ) {
// transfer func
- strongUpdate = rg.assignTempXFieldFEqualToTempY(lhs, fld, rhs, fn);
-
+ strongUpdate = rg.assignTempXFieldFEqualToTempY( lhs,
+ fld,
+ rhs,
+ fn,
+ edgeKeysRemoved,
+ edgeKeysAdded );
if( doDefiniteReachAnalysis ) {
- definiteReachAnalysis.store( fn, lhs, fld, rhs );
+ definiteReachAnalysis.store( fn,
+ lhs,
+ fld,
+ rhs,
+ edgeKeysRemoved,
+ edgeKeysAdded );
+ didDefReachTransfer = true;
}
}
}
}
+ edgeKeysForLoad = null;
+ if( doDefiniteReachAnalysis ) {
+ edgeKeysForLoad = new HashSet<EdgeKey>();
+ }
+
if( shouldAnalysisTrack(lhs.getType() ) ) {
// transfer func
- rg.assignTempXEqualToTempYFieldF(lhs, rhs, fdElement, fn);
+ rg.assignTempXEqualToTempYFieldF( lhs, rhs, fdElement, fn, edgeKeysForLoad );
if( doDefiniteReachAnalysis ) {
- definiteReachAnalysis.load( fn, lhs, rhs, fdElement );
+ definiteReachAnalysis.load( fn, lhs, rhs, fdElement, edgeKeysForLoad );
+ didDefReachTransfer = true;
}
}
lhs = fsen.getDst();
rhs = fsen.getSrc();
-
+
assert lhs.getType() != null;
assert lhs.getType().isArray();
tdElement = lhs.getType().dereference();
fdElement = getArrayField(tdElement);
+ edgeKeysRemoved = null;
+ edgeKeysAdded = null;
+ if( doDefiniteReachAnalysis ) {
+ edgeKeysRemoved = new HashSet<EdgeKey>();
+ edgeKeysAdded = new HashSet<EdgeKey>();
+ }
+
// before transfer func, possibly inject
// stall-site taints
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
// transfer func, BUT
// skip this node if it cannot create new reachability paths
if( !arrayReferencees.doesNotCreateNewReaching(fsen) ) {
- rg.assignTempXFieldFEqualToTempY(lhs, fdElement, rhs, fn);
+ rg.assignTempXFieldFEqualToTempY( lhs,
+ fdElement,
+ rhs,
+ fn,
+ edgeKeysRemoved,
+ edgeKeysAdded );
}
if( doDefiniteReachAnalysis ) {
- definiteReachAnalysis.store( fn, lhs, fdElement, rhs );
+ definiteReachAnalysis.store( fn,
+ lhs,
+ fdElement,
+ rhs,
+ edgeKeysRemoved,
+ edgeKeysAdded );
+ didDefReachTransfer = true;
}
}
if( doDefiniteReachAnalysis ) {
definiteReachAnalysis.newObject( fn, lhs );
+ didDefReachTransfer = true;
}
}
break;
if( doDefiniteReachAnalysis ) {
definiteReachAnalysis.methodCall( fn, fc.getReturnTemp() );
+ didDefReachTransfer = true;
}
fc2enclosing.put(fc, mdCaller);
if( state.DISJOINTDEBUGSCHEDULING ) {
- System.out.println(" context changed, scheduling callee: "+mdPossible);
+ System.out.println(" context changed at callsite: "+fc+", scheduling callee: "+mdPossible);
}
if( state.DISJOINTDVISITSTACKEESONTOP ) {
} // end switch
+
+ if( doDefiniteReachAnalysis && !didDefReachTransfer ) {
+ definiteReachAnalysis.otherStatement( fn );
+ }
+
+
+
// dead variables were removed before the above transfer function
// was applied, so eliminate heap regions and edges that are no
// longer part of the abstractly-live heap graph, and sweep up
Hashtable<FlatCall, ReachGraph> heapsFromCallers =
getIHMcontributions(d);
- heapsFromCallers.put(fc, rg);
+ // ensure inputs to initial contexts increase monotonically
+ ReachGraph merged = new ReachGraph();
+ merged.merge( rg );
+ merged.merge( heapsFromCallers.get( fc ) );
+
+ heapsFromCallers.put( fc, merged );
+
}