// only consider the subest of the caller elements that
- // are reachable by callee when testing predicates
- public boolean isSatisfiedBy( ReachGraph rg,
- Set<HeapRegionNode> calleeReachableNodes,
- Set<RefEdge> calleeReachableEdges
- ) {
+ // are reachable by callee when testing predicates--if THIS
+ // predicate is satisfied, return the predicate set of the
+ // element that satisfied it, or null for false
+ public ExistPredSet isSatisfiedBy( ReachGraph rg,
+ Set<HeapRegionNode> calleeReachableNodes,
+ Set<RefEdge> calleeReachableEdges
+ ) {
if( predType == TYPE_TRUE ) {
- return true;
+ return ExistPredSet.factory( ExistPred.factory() );
}
if( predType == TYPE_NODE ) {
// first find node
HeapRegionNode hrn = rg.id2hrn.get( n_hrnID );
if( hrn == null ) {
- return false;
+ return null;
}
if( !calleeReachableNodes.contains( hrn ) ) {
- return false;
+ return null;
}
// when the state is null it is not part of the
// predicate, so we've already satisfied
if( ne_state == null ) {
- return true;
+ return hrn.getPreds();
}
// otherwise look for state too
// TODO: contains OR containsSuperSet OR containsWithZeroes??
- return hrn.getAlpha().contains( ne_state );
+ if( hrn.getAlpha().contains( ne_state ) ) {
+ return hrn.getPreds();
+ }
+
+ return null;
}
if( predType == TYPE_EDGE ) {
// the source is not present in graph
if( vnSrc == null && hrnSrc == null ) {
- return false;
+ return null;
}
RefSrcNode rsn;
rsn = vnSrc;
} else {
if( !calleeReachableNodes.contains( hrnSrc ) ) {
- return false;
+ return null;
}
rsn = hrnSrc;
}
// is the destination present?
HeapRegionNode hrnDst = rg.id2hrn.get( e_hrnDstID );
if( hrnDst == null ) {
- return false;
+ return null;
}
if( !calleeReachableNodes.contains( hrnDst ) ) {
- return false;
+ return null;
}
// is there an edge between them with the given
e_type,
e_field );
if( edge == null ) {
- return false;
+ return null;
}
if( !calleeReachableEdges.contains( edge ) ) {
- return false;
+ return null;
}
// when state is null it is not part of the predicate
// so we've satisfied the edge existence
if( ne_state == null ) {
- return true;
+ return edge.getPreds();
}
// otherwise look for state too
// TODO: contains OR containsSuperSet OR containsWithZeroes??
- return hrnDst.getAlpha().contains( ne_state );
+ if( hrnDst.getAlpha().contains( ne_state ) ) {
+ return edge.getPreds();
+ }
+
+ return null;
}
throw new Error( "Unknown predicate type" );
TypeDescriptor tdNewEdge =
mostSpecificType( edgeHrn.getType(),
hrnHrn.getType()
- );
+ );
RefEdge edgeNew = new RefEdge( lnX,
hrnHrn,
predsTrue
);
- addRefEdge( lnX, hrnHrn, edgeNew );
+ addRefEdge( lnX, hrnHrn, edgeNew );
}
}
return rg;
}
+
+
public void
resolveMethodCall( FlatCall fc,
FlatMethod fm,
// 1. mark what callee elements have satisfied predicates
- Set<HeapRegionNode> calleeNodesSatisfied =
- new HashSet<HeapRegionNode>();
+ Hashtable<HeapRegionNode, ExistPredSet> calleeNodesSatisfied =
+ new Hashtable<HeapRegionNode, ExistPredSet>();
- Set<RefEdge> calleeEdgesSatisfied =
- new HashSet<RefEdge>();
+ Hashtable<RefEdge, ExistPredSet> calleeEdgesSatisfied =
+ new Hashtable<RefEdge, ExistPredSet>();
Iterator meItr = rgCallee.id2hrn.entrySet().iterator();
while( meItr.hasNext() ) {
Integer id = (Integer) me.getKey();
HeapRegionNode hrnCallee = (HeapRegionNode) me.getValue();
- if( hrnCallee.getPreds().isSatisfiedBy( this,
- callerNodesCopiedToCallee,
- callerEdgesCopiedToCallee
- )
- ) {
- calleeNodesSatisfied.add( hrnCallee );
+ ExistPredSet predsIfSatis =
+ hrnCallee.getPreds().isSatisfiedBy( this,
+ callerNodesCopiedToCallee,
+ callerEdgesCopiedToCallee
+ );
+ if( predsIfSatis != null ) {
+ calleeNodesSatisfied.put( hrnCallee, predsIfSatis );
+ } else {
+ // otherwise don't bother looking at edges from this node
+ continue;
}
Iterator<RefEdge> reItr = hrnCallee.iteratorToReferencees();
while( reItr.hasNext() ) {
RefEdge reCallee = reItr.next();
+
+ ExistPredSet ifDst =
+ reCallee.getDst().getPreds().isSatisfiedBy( this,
+ callerNodesCopiedToCallee,
+ callerEdgesCopiedToCallee
+ );
+ if( ifDst == null ) {
+ continue;
+ }
- if( reCallee.getPreds().isSatisfiedBy( this,
- callerNodesCopiedToCallee,
- callerEdgesCopiedToCallee
- )
- ) {
- calleeEdgesSatisfied.add( reCallee );
+ predsIfSatis =
+ reCallee.getPreds().isSatisfiedBy( this,
+ callerNodesCopiedToCallee,
+ callerEdgesCopiedToCallee
+ );
+ if( predsIfSatis != null ) {
+ calleeEdgesSatisfied.put( reCallee, predsIfSatis );
}
}
}
Iterator<RefEdge> reItr = vnCallee.iteratorToReferencees();
while( reItr.hasNext() ) {
RefEdge reCallee = reItr.next();
-
- if( reCallee.getPreds().isSatisfiedBy( this,
- callerNodesCopiedToCallee,
- callerEdgesCopiedToCallee
- )
- ) {
- calleeEdgesSatisfied.add( reCallee );
+
+ ExistPredSet ifDst =
+ reCallee.getDst().getPreds().isSatisfiedBy( this,
+ callerNodesCopiedToCallee,
+ callerEdgesCopiedToCallee
+ );
+ if( ifDst == null ) {
+ continue;
+ }
+
+ ExistPredSet predsIfSatis =
+ reCallee.getPreds().isSatisfiedBy( this,
+ callerNodesCopiedToCallee,
+ callerEdgesCopiedToCallee
+ );
+ if( predsIfSatis != null ) {
+ calleeEdgesSatisfied.put( reCallee, predsIfSatis );
}
}
}
- // 3. callee elements with satisfied preds come in
+ // 3. callee elements with satisfied preds come in, note that
+ // the mapping of elements satisfied to preds is like this:
+ // A callee element EE has preds EEp that are satisfied by
+ // some caller element ER. We bring EE into the caller
+ // context as ERee with the preds of ER, namely ERp, which
+ // in the following algorithm is the value in the mapping
// 3.a) nodes
- hrnItr = calleeNodesSatisfied.iterator();
- while( hrnItr.hasNext() ) {
- HeapRegionNode hrnCallee = hrnItr.next();
+ Iterator satisItr = calleeNodesSatisfied.entrySet().iterator();
+ while( satisItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) satisItr.next();
+ HeapRegionNode hrnCallee = (HeapRegionNode) me.getKey();
+ ExistPredSet preds = (ExistPredSet) me.getValue();
if( hrnCallee.isOutOfContext() ) {
continue;
hrnCallee.getAllocSite(), // allocation site
hrnCallee.getInherent(), // inherent reach
null, // current reach
- predsEmpty, // predicates
+ preds, // predicates
hrnCallee.getDescription() // description
);
}
// TODO: alpha should be some rewritten version of callee in caller context
hrnCaller.setAlpha( rsetEmpty );
-
- // TODO: predicates should be exact same from caller version that satisfied
- hrnCaller.setPreds( predsTrue );
}
// 3.b) callee -> callee edges
- Iterator<RefEdge> reItr = calleeEdgesSatisfied.iterator();
- while( reItr.hasNext() ) {
- RefEdge reCallee = reItr.next();
+ satisItr = calleeEdgesSatisfied.entrySet().iterator();
+ while( satisItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) satisItr.next();
+ RefEdge reCallee = (RefEdge) me.getKey();
+ ExistPredSet preds = (ExistPredSet) me.getValue();
RefSrcNode rsnCallee = reCallee.getSrc();
RefSrcNode rsnCaller;
HeapRegionNode hrnSrcCallee = (HeapRegionNode) reCallee.getSrc();
rsnCaller = id2hrn.get( hrnSrcCallee.getID() );
}
-
+
assert rsnCaller != null;
HeapRegionNode hrnDstCallee = reCallee.getDst();
HeapRegionNode hrnDstCaller = id2hrn.get( hrnDstCallee.getID() );
assert hrnDstCaller != null;
- // TODO: beta rewrites, preds from satisfier in caller
+ // TODO: beta rewrites
RefEdge reCaller = new RefEdge( rsnCaller,
hrnDstCaller,
reCallee.getType(),
reCallee.getField(),
rsetEmpty,
- predsTrue
+ preds
);