// every program point
private Map<FlatNode, DefiniteReachState> fn2state;
- private static PointerMethod pm;
+ // even though the above map has a set of nodes that
+ // have been analyzed, we need a per-intra pass set
+ // of nodes that have been analyzed, too, to filter
+ // out nodes that do not have a partial result yet
+ private Set<FlatNode> fnHasPartial;
- public static void setPointerMethod( PointerMethod pm ) {
- DefiniteReachAnalysis.pm = pm;
- }
+
+ private static PointerMethod pm;
- public DefiniteReachAnalysis() {
+ public DefiniteReachAnalysis( PointerMethod pm ) {
// a class-wide initialization
DefiniteReachState.initBuilders();
+
+ DefiniteReachAnalysis.pm = pm;
- fn2state = new HashMap<FlatNode, DefiniteReachState>();
+ fn2state = new HashMap<FlatNode, DefiniteReachState>();
+ fnHasPartial = new HashSet<FlatNode>();
+ }
+
+
+ private void addPartialResult( FlatNode fn, DefiniteReachState state ) {
+ fn2state.put( fn, state );
+ fnHasPartial.add( fn );
}
public void methodEntry( FlatNode fn,
Set<TempDescriptor> parameters ) {
+ // this should be called exactly once at the beginning
+ // of any intraprocedural pass, so clear partial result
+ // set
+ fnHasPartial.clear();
+
DefiniteReachState state = makeIn( fn );
state.methodEntry( parameters );
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void copy( FlatNode fn,
TempDescriptor y ) {
DefiniteReachState state = makeIn( fn );
state.copy( x, y );
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void load( FlatNode fn,
DefiniteReachState state = makeIn( fn );
state.load( x, y, f, edgeKeysForLoad );
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void store( FlatNode fn,
DefiniteReachState state = makeIn( fn );
state.store( x, f, y, edgeKeysRemoved, edgeKeysAdded );
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void newObject( FlatNode fn,
TempDescriptor x ) {
DefiniteReachState state = makeIn( fn );
state.newObject( x );
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void methodCall( FlatNode fn,
if( retVal != null ) {
state.methodCall( retVal );
}
- fn2state.put( fn, state );
+ addPartialResult( fn, state );
}
public void otherStatement( FlatNode fn ) {
- fn2state.put( fn, makeIn( fn ) );
+ addPartialResult( fn, makeIn( fn ) );
}
return state;
}
+
// get the current state for the program point just
// before the given program point by merging the out
// states of the predecessor statements
public DefiniteReachState makeIn( FlatNode fn ) {
+
if( pm.numPrev( fn ) == 0 ) {
return new DefiniteReachState();
}
DefiniteReachState stateIn = null;
for( int i = 0; i < pm.numPrev( fn ); ++i ) {
-
- if( fn2state.containsKey( pm.getPrev( fn, i ) ) ) {
+ if( fnHasPartial.contains( pm.getPrev( fn, i ) ) ) {
if( stateIn == null ) {
// duplicate the first partial result we find
stateIn = new DefiniteReachState( get( pm.getPrev( fn, i ) ) );
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 ) {
for( MultiKey key : this.R.get().keySet() ) {
if( that.R.get( viewRfull, key ).isEmpty() ) {
this.R.remove( viewRfull, key );
+ } else {
+ // if the key is in this and that, we should join the
+ // values using the R.joinOp which is currently has no
+ // public interface
}
}
}