-
-
// call before instantiating this class
static public void initBuilders() {
RBuilder =
}
+
+ public boolean isAlreadyReachable( TempDescriptor a,
+ TempDescriptor b ) {
+ return !R.get( viewR01, MultiKey.factory( a, b ) ).isEmpty();
+ }
+
+
+
+
public void methodEntry( Set<TempDescriptor> parameters ) {
methodEntryR( parameters );
public void methodEntryR( Set<TempDescriptor> parameters ) {
- //R.clear();
+ R.clear();
}
public void copyR( TempDescriptor x,
TempDescriptor y ) {
// consider that x and y can be the same, so do the
// parts of the update in the right order:
- /*
+
// first get all info for update
MultiKey keyY = MultiKey.factory( y );
Map<MultiKey, Object> mapY0 = R.get( viewR0, keyY );
fullKeyY.get( 2 ) );
R.put( fullKeyX, MultiViewMap.dummyValue );
}
- */
}
public void loadR( TempDescriptor x,
TempDescriptor y,
FieldDescriptor f,
Set<EdgeKey> edgeKeysForLoad ) {
- /*
// consider that x and y can be the same, so do the
// parts of the update in the right order:
MultiViewMap.dummyValue );
}
}
- */
}
public void storeR( TempDescriptor x,
}
public void newObjectR( TempDescriptor x ) {
- /*
MultiKey keyX = MultiKey.factory( x );
R.remove( viewR0, keyX );
R.remove( viewR1, keyX );
- */
}
public void methodCallR( TempDescriptor retVal ) {
- /*
MultiKey keyRetVal = MultiKey.factory( retVal );
R.remove( viewR0, keyRetVal );
R.remove( viewR1, keyRetVal );
- */
}
public void mergeR( DefiniteReachState that ) {
FlatSESEEnterNode sese;
FlatSESEExitNode fsexn;
+ boolean alreadyReachable;
Set<EdgeKey> edgeKeysForLoad;
Set<EdgeKey> edgeKeysRemoved;
Set<EdgeKey> edgeKeysAdded;
boolean strongUpdate = false;
- edgeKeysRemoved = null;
- edgeKeysAdded = null;
+ alreadyReachable = false;
+ edgeKeysRemoved = null;
+ edgeKeysAdded = null;
if( doDefiniteReachAnalysis ) {
- edgeKeysRemoved = new HashSet<EdgeKey>();
- edgeKeysAdded = new HashSet<EdgeKey>();
+ alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
+ edgeKeysRemoved = new HashSet<EdgeKey>();
+ edgeKeysAdded = new HashSet<EdgeKey>();
}
// before transfer func, possibly inject
fld,
rhs,
fn,
+ alreadyReachable,
edgeKeysRemoved,
edgeKeysAdded );
if( doDefiniteReachAnalysis ) {
tdElement = lhs.getType().dereference();
fdElement = getArrayField(tdElement);
- edgeKeysRemoved = null;
- edgeKeysAdded = null;
+ alreadyReachable = false;
+ edgeKeysRemoved = null;
+ edgeKeysAdded = null;
if( doDefiniteReachAnalysis ) {
+ alreadyReachable = definiteReachAnalysis.isAlreadyReachable( rhs, lhs, fn );
edgeKeysRemoved = new HashSet<EdgeKey>();
edgeKeysAdded = new HashSet<EdgeKey>();
}
fdElement,
rhs,
fn,
+ alreadyReachable,
edgeKeysRemoved,
edgeKeysAdded );
}
fdStringBytesField,
tdStrLiteralBytes,
null,
+ false,
null,
null );
}
FieldDescriptor f,
TempDescriptor y,
FlatNode currentProgramPoint,
+ boolean alreadyReachable,
Set<EdgeKey> edgeKeysRemoved,
Set<EdgeKey> edgeKeysAdded
) {
}
}
- // then do all token propagation
- itrXhrn = lnX.iteratorToReferencees();
- while( itrXhrn.hasNext() ) {
- RefEdge edgeX = itrXhrn.next();
- HeapRegionNode hrnX = edgeX.getDst();
- ReachSet betaX = edgeX.getBeta();
- ReachSet R = Canonical.intersection(hrnX.getAlpha(),
- edgeX.getBeta()
- );
- Iterator<RefEdge> itrYhrn = lnY.iteratorToReferencees();
- while( itrYhrn.hasNext() ) {
- RefEdge edgeY = itrYhrn.next();
- HeapRegionNode hrnY = edgeY.getDst();
- ReachSet O = edgeY.getBeta();
+ // definite reachability analysis can elide reachability propagation
+ if( !alreadyReachable ) {
- // check for impossible edges
- if( !isSuperiorType(f.getType(), edgeY.getType() ) ) {
- impossibleEdges.add(edgeY);
- continue;
- }
+ // then do all token propagation
+ itrXhrn = lnX.iteratorToReferencees();
+ while( itrXhrn.hasNext() ) {
+ RefEdge edgeX = itrXhrn.next();
+ HeapRegionNode hrnX = edgeX.getDst();
+ ReachSet betaX = edgeX.getBeta();
+ ReachSet R = Canonical.intersection(hrnX.getAlpha(),
+ edgeX.getBeta()
+ );
- // propagate tokens over nodes starting from hrnSrc, and it will
- // take care of propagating back up edges from any touched nodes
- ChangeSet Cy = Canonical.unionUpArityToChangeSet(O, R);
- propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta);
+ Iterator<RefEdge> itrYhrn = lnY.iteratorToReferencees();
+ while( itrYhrn.hasNext() ) {
+ RefEdge edgeY = itrYhrn.next();
+ HeapRegionNode hrnY = edgeY.getDst();
+ ReachSet O = edgeY.getBeta();
- // then propagate back just up the edges from hrn
- ChangeSet Cx = Canonical.unionUpArityToChangeSet(R, O);
- HashSet<RefEdge> todoEdges = new HashSet<RefEdge>();
+ // check for impossible edges
+ if( !isSuperiorType(f.getType(), edgeY.getType() ) ) {
+ impossibleEdges.add(edgeY);
+ continue;
+ }
- Hashtable<RefEdge, ChangeSet> edgePlannedChanges =
- new Hashtable<RefEdge, ChangeSet>();
+ // propagate tokens over nodes starting from hrnSrc, and it will
+ // take care of propagating back up edges from any touched nodes
+ ChangeSet Cy = Canonical.unionUpArityToChangeSet(O, R);
+ propagateTokensOverNodes(hrnY, Cy, nodesWithNewAlpha, edgesWithNewBeta);
- Iterator<RefEdge> referItr = hrnX.iteratorToReferencers();
- while( referItr.hasNext() ) {
- RefEdge edgeUpstream = referItr.next();
- todoEdges.add(edgeUpstream);
- edgePlannedChanges.put(edgeUpstream, Cx);
- }
+ // then propagate back just up the edges from hrn
+ ChangeSet Cx = Canonical.unionUpArityToChangeSet(R, O);
+ HashSet<RefEdge> todoEdges = new HashSet<RefEdge>();
+
+ Hashtable<RefEdge, ChangeSet> edgePlannedChanges =
+ new Hashtable<RefEdge, ChangeSet>();
- propagateTokensOverEdges(todoEdges,
- edgePlannedChanges,
- edgesWithNewBeta);
+ Iterator<RefEdge> referItr = hrnX.iteratorToReferencers();
+ while( referItr.hasNext() ) {
+ RefEdge edgeUpstream = referItr.next();
+ todoEdges.add(edgeUpstream);
+ edgePlannedChanges.put(edgeUpstream, Cx);
+ }
+
+ propagateTokensOverEdges(todoEdges,
+ edgePlannedChanges,
+ edgesWithNewBeta);
+ }
}
}
-
+
// apply the updates to reachability
Iterator<HeapRegionNode> nodeItr = nodesWithNewAlpha.iterator();
currentProgramPoint);
}
+
+ ReachSet betaNew;
+ if( alreadyReachable ) {
+ betaNew = edgeY.getBeta();
+ } else {
+ betaNew = Canonical.pruneBy( edgeY.getBeta(),
+ hrnX.getAlpha() );
+ }
+
+
RefEdge edgeNew =
new RefEdge(hrnX,
hrnY,
tdNewEdge,
f.getSymbol(),
- Canonical.changePredsTo(
- Canonical.pruneBy(edgeY.getBeta(),
- hrnX.getAlpha()
- ),
- predsTrue
- ),
+ Canonical.changePredsTo( betaNew,
+ predsTrue ),
predsTrue,
taints
);