// 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 ) ) );