// a special out-of-scope temp
protected static final TempDescriptor tdReturn = new TempDescriptor( "_Return___" );
+
+ // predicate constants
+ public static final ExistPred predTrue = ExistPred.factory(); // if no args, true
+ public static final ExistPredSet predsEmpty = ExistPredSet.factory();
+ public static final ExistPredSet predsTrue = ExistPredSet.factory( predTrue );
// some frequently used reachability constants
protected static final ReachState rstateEmpty = ReachState.factory();
protected static final ReachSet rsetEmpty = ReachSet.factory();
- protected static final ReachSet rsetWithEmptyState = Canonical.makePredsTrue(ReachSet.factory( rstateEmpty ));
-
- // predicate constants
- protected static final ExistPred predTrue = ExistPred.factory(); // if no args, true
- protected static final ExistPredSet predsEmpty = ExistPredSet.factory();
- protected static final ExistPredSet predsTrue = ExistPredSet.factory( predTrue );
-
+ protected static final ReachSet rsetWithEmptyState = Canonical.changePredsTo( ReachSet.factory( rstateEmpty ),
+ predsTrue );
// from DisjointAnalysis for convenience
protected static int allocationDepth = -1;
// convenient set of alloc sites for all heap regions
// present in the graph without having to search
public HashSet<AllocSite> allocSites;
+
+ // set of accessible variables for current program statement
+ // if not contains, it is an inaccessible variable
+ public HashSet<TempDescriptor> accessibleVars;
public ReachGraph() {
id2hrn = new Hashtable<Integer, HeapRegionNode>();
td2vn = new Hashtable<TempDescriptor, VariableNode >();
allocSites = new HashSet<AllocSite>();
+ accessibleVars = new HashSet<TempDescriptor>();
}
if( inherent == null ) {
if( markForAnalysis ) {
inherent =
- Canonical.makePredsTrue(
+ Canonical.changePredsTo(
ReachSet.factory(
ReachState.factory(
ReachTuple.factory( id,
false // out-of-context
)
)
- )
+ ),
+ predsTrue
);
} else {
inherent = rsetWithEmptyState;
}
- protected void clearRefEdgesFrom( RefSrcNode referencer,
- TypeDescriptor type,
- String field,
- boolean removeAll ) {
+ // return whether at least one edge was removed
+ protected boolean clearRefEdgesFrom( RefSrcNode referencer,
+ TypeDescriptor type,
+ String field,
+ boolean removeAll ) {
assert referencer != null;
+ boolean atLeastOneEdgeRemoved = false;
+
// get a copy of the set to iterate over, otherwise
// we will be trying to take apart the set as we
// are iterating over it, which won't work
referencee,
edge.getType(),
edge.getField() );
+
+ atLeastOneEdgeRemoved = true;
}
}
+
+ return atLeastOneEdgeRemoved;
}
protected void clearRefEdgesTo( HeapRegionNode referencee,
edgeNew.getPreds()
)
);
-
+ edgeExisting.setTaints(
+ Canonical.unionORpreds( edgeExisting.getTaints(),
+ edgeNew.getTaints()
+ )
+ );
+
} else {
addRefEdge( src, dst, edgeNew );
}
public void assignTempXEqualToTempY( TempDescriptor x,
TempDescriptor y ) {
assignTempXEqualToCastedTempY( x, y, null );
+
+ // x gets status of y
+ // if it is in region,
+ //if(accessibleVars.contains(y)){
+ // accessibleVars.add(x);
+ //}
}
public void assignTempXEqualToCastedTempY( TempDescriptor x,
null,
Canonical.intersection( betaY, betaHrn ),
predsTrue,
- null,
- null
+ edgeY.getTaints()
);
addEdgeOrMergeWithExisting( edgeNew );
if( !DISABLE_GLOBAL_SWEEP ) {
globalSweep();
}
- }
+ }
+
+ // accessible status update
+ // if it is in region,
+ //accessibleVars.add(x);
+ //accessibleVars.add(y);
}
- public void assignTempXFieldFEqualToTempY( TempDescriptor x,
- FieldDescriptor f,
- TempDescriptor y ) {
+ // return whether a strong update was actually effected
+ public boolean assignTempXFieldFEqualToTempY( TempDescriptor x,
+ FieldDescriptor f,
+ TempDescriptor y ) {
VariableNode lnX = getVariableNodeFromTemp( x );
VariableNode lnY = getVariableNodeFromTemp( y );
Set<RefEdge> impossibleEdges = new HashSet<RefEdge>();
// first look for possible strong updates and remove those edges
- boolean strongUpdate = false;
+ boolean strongUpdateCond = false;
+ boolean edgeRemovedByStrongUpdate = false;
Iterator<RefEdge> itrXhrn = lnX.iteratorToReferencees();
while( itrXhrn.hasNext() ) {
)
) {
if( !DISABLE_STRONG_UPDATES ) {
- strongUpdate = true;
- clearRefEdgesFrom( hrnX, f.getType(), f.getSymbol(), false );
+ strongUpdateCond = true;
+
+ boolean atLeastOne =
+ clearRefEdgesFrom( hrnX,
+ f.getType(),
+ f.getSymbol(),
+ false );
+ if( atLeastOne ) {
+ edgeRemovedByStrongUpdate = true;
+ }
}
}
}
hrnY,
tdNewEdge,
f.getSymbol(),
- Canonical.makePredsTrue(
+ Canonical.changePredsTo(
Canonical.pruneBy( edgeY.getBeta(),
hrnX.getAlpha()
- )
+ ),
+ predsTrue
),
predsTrue,
- null,
- null
+ Canonical.changePredsTo( edgeY.getTaints(),
+ predsTrue )
);
addEdgeOrMergeWithExisting( edgeNew );
// if there was a strong update, make sure to improve
// reachability with a global sweep
- if( strongUpdate || !impossibleEdges.isEmpty() ) {
+ if( edgeRemovedByStrongUpdate || !impossibleEdges.isEmpty() ) {
if( !DISABLE_GLOBAL_SWEEP ) {
globalSweep();
}
}
+
+
+ // after x.y=f , stall x and y if they are not accessible
+ // also contribute write effects on stall site of x
+ // accessible status update
+ // if it is in region
+ //accessibleVars.add(x);
+ //accessibleVars.add(y);
+
+ return edgeRemovedByStrongUpdate;
}
HeapRegionNode referencee = edgeX.getDst();
RefEdge edgeNew = edgeX.copy();
edgeNew.setSrc( lnR );
+ edgeNew.setTaints( Canonical.changePredsTo( edgeNew.getTaints(),
+ predsTrue
+ )
+ );
addRefEdge( lnR, referencee, edgeNew );
}
null, // field name
hrnNewest.getAlpha(), // beta
predsTrue, // predicates
- null, null
+ TaintSet.factory() // taints
);
addRefEdge( lnX, hrnNewest, edgeNew );
+
+ // after x=new , x is accessible
+ // if (isInRegion()) {
+ //accessibleVars.add(x);
}
}
+ public void taintInSetVars( FlatSESEEnterNode sese ) {
+ if( sese.getIsCallerSESEplaceholder() ) {
+ return;
+ }
+
+ Iterator<TempDescriptor> isvItr = sese.getInVarSet().iterator();
+ while( isvItr.hasNext() ) {
+ TempDescriptor isv = isvItr.next();
+ VariableNode vn = getVariableNodeFromTemp( isv );
+
+ Iterator<RefEdge> reItr = vn.iteratorToReferencees();
+ while( reItr.hasNext() ) {
+ RefEdge re = reItr.next();
+
+ // these in-set taints should have empty
+ // predicates so they never propagate
+ // out to callers
+ Taint t = Taint.factory( sese,
+ null,
+ isv,
+ re.getDst().getAllocSite(),
+ ExistPredSet.factory()
+ );
+
+ re.setTaints( Canonical.add( re.getTaints(),
+ t
+ )
+ );
+ }
+ }
+ }
+
+ // this is useful for more general tainting
+ public void taintTemp( Taint taint,
+ TempDescriptor td,
+ ExistPredSet preds
+ ) {
+
+ VariableNode vn = getVariableNodeFromTemp( td );
+
+ Iterator<RefEdge> reItr = vn.iteratorToReferencees();
+ while( reItr.hasNext() ) {
+ RefEdge re = reItr.next();
+
+ re.setTaints( Canonical.add( re.getTaints(),
+ taint
+ )
+ );
+ }
+ }
+
+ public void removeInContextTaints( FlatSESEEnterNode sese ) {
+ if( sese.getIsCallerSESEplaceholder() ) {
+ return;
+ }
+
+ Iterator meItr = id2hrn.entrySet().iterator();
+ while( meItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) meItr.next();
+ Integer id = (Integer) me.getKey();
+ HeapRegionNode hrn = (HeapRegionNode) me.getValue();
+
+ Iterator<RefEdge> reItr = hrn.iteratorToReferencers();
+ while( reItr.hasNext() ) {
+ RefEdge re = reItr.next();
+
+ re.setTaints( Canonical.removeTaintsBy( re.getTaints(),
+ sese
+ )
+ );
+ }
+ }
+ }
+
+
// used in makeCalleeView below to decide if there is
// already an appropriate out-of-context edge in a callee
// view graph for merging, or null if a new one will be added
// used below to convert a ReachSet to its callee-context
// equivalent with respect to allocation sites in this graph
protected ReachSet toCalleeContext( ReachSet rs,
- ExistPredSet preds,
+ ExistPredSet predsNodeOrEdge,
Set<HrnIdOoc> oocHrnIdOoc2callee
) {
ReachSet out = ReachSet.factory();
stateCallee = stateNew;
}
- // attach the passed in preds
- stateCallee = Canonical.attach( stateCallee,
- preds );
+ // make a predicate of the caller graph element
+ // and the caller state we just converted
+ ExistPredSet predsWithState = ExistPredSet.factory();
+
+ Iterator<ExistPred> predItr = predsNodeOrEdge.iterator();
+ while( predItr.hasNext() ) {
+ ExistPred predNodeOrEdge = predItr.next();
+
+ predsWithState =
+ Canonical.add( predsWithState,
+ ExistPred.factory( predNodeOrEdge.n_hrnID,
+ predNodeOrEdge.e_tdSrc,
+ predNodeOrEdge.e_hrnSrcID,
+ predNodeOrEdge.e_hrnDstID,
+ predNodeOrEdge.e_type,
+ predNodeOrEdge.e_field,
+ stateCallee,
+ null,
+ predNodeOrEdge.e_srcOutCalleeContext,
+ predNodeOrEdge.e_srcOutCallerContext
+ )
+ );
+ }
+ stateCallee = Canonical.changePredsTo( stateCallee,
+ predsWithState );
+
out = Canonical.add( out,
stateCallee
- );
-
+ );
}
assert out.isCanonical();
return out;
) {
ReachSet out = ReachSet.factory();
+ // when the mapping is null it means there were no
+ // predicates satisfied
+ if( calleeStatesSatisfied == null ) {
+ return out;
+ }
+
Iterator<ReachState> itr = rs.iterator();
while( itr.hasNext() ) {
ReachState stateCallee = itr.next();
return out;
}
+
// used below to convert a ReachSet to an equivalent
// version with shadow IDs merged into unshadowed IDs
protected ReachSet unshadow( ReachSet rs ) {
}
+ // convert a caller taint set into a callee taint set
+ protected TaintSet
+ toCalleeContext( TaintSet ts,
+ ExistPredSet predsEdge ) {
+
+ TaintSet out = TaintSet.factory();
+
+ // the idea is easy, the taint identifier itself doesn't
+ // change at all, but the predicates should be tautology:
+ // start with the preds passed in from the caller edge
+ // that host the taints, and alter them to have the taint
+ // added, just becoming more specific than edge predicate alone
+
+ Iterator<Taint> itr = ts.iterator();
+ while( itr.hasNext() ) {
+ Taint tCaller = itr.next();
+
+ ExistPredSet predsWithTaint = ExistPredSet.factory();
+
+ Iterator<ExistPred> predItr = predsEdge.iterator();
+ while( predItr.hasNext() ) {
+ ExistPred predEdge = predItr.next();
+
+ predsWithTaint =
+ Canonical.add( predsWithTaint,
+ ExistPred.factory( predEdge.e_tdSrc,
+ predEdge.e_hrnSrcID,
+ predEdge.e_hrnDstID,
+ predEdge.e_type,
+ predEdge.e_field,
+ null,
+ tCaller,
+ predEdge.e_srcOutCalleeContext,
+ predEdge.e_srcOutCallerContext
+ )
+ );
+ }
+
+ Taint tCallee = Canonical.changePredsTo( tCaller,
+ predsWithTaint );
+
+ out = Canonical.add( out,
+ tCallee
+ );
+ }
+
+ assert out.isCanonical();
+ return out;
+ }
+
+
+ // used below to convert a TaintSet to its caller-context
+ // equivalent, just eliminate Taints with bad preds
+ protected TaintSet
+ toCallerContext( TaintSet ts,
+ Hashtable<Taint, ExistPredSet> calleeTaintsSatisfied
+ ) {
+
+ TaintSet out = TaintSet.factory();
+
+ // when the mapping is null it means there were no
+ // predicates satisfied
+ if( calleeTaintsSatisfied == null ) {
+ return out;
+ }
+
+ Iterator<Taint> itr = ts.iterator();
+ while( itr.hasNext() ) {
+ Taint tCallee = itr.next();
+
+ if( calleeTaintsSatisfied.containsKey( tCallee ) ) {
+
+ Taint tCaller =
+ Canonical.attach( Taint.factory( tCallee.sese,
+ tCallee.stallSite,
+ tCallee.var,
+ tCallee.allocSite,
+ ExistPredSet.factory() ),
+ calleeTaintsSatisfied.get( tCallee )
+ );
+ out = Canonical.add( out,
+ tCaller
+ );
+ }
+ }
+
+ assert out.isCanonical();
+ return out;
+ }
+
+
+
+
// use this method to make a new reach graph that is
// what heap the FlatMethod callee from the FlatCall
// would start with reaching from its arguments in
),
toCalleeContext( hrnCaller.getAlpha(),
preds,
- oocHrnIdOoc2callee
+ oocHrnIdOoc2callee
),
preds,
hrnCaller.getDescription()
hrnDstCallee.getID(),
reArg.getType(),
reArg.getField(),
- null,
+ null, // state
+ null, // taint
true, // out-of-callee-context
false // out-of-caller-context
);
ExistPredSet preds =
ExistPredSet.factory( pred );
-
- Taint paramTaint =
- Taint.factory( index, paramCallee.toString() );
-
- TaintSet paramTaints =
- TaintSet.factory( paramTaint );
RefEdge reCallee =
new RefEdge( vnCallee,
oocHrnIdOoc2callee
),
preds,
- paramTaints,
- null
+ toCalleeContext( reArg.getTaints(),
+ preds )
);
rg.addRefEdge( vnCallee,
hrnDstCallee.getID(),
reCaller.getType(),
reCaller.getField(),
- null,
+ null, // state
+ null, // taint
false, // out-of-callee-context
false // out-of-caller-context
);
oocHrnIdOoc2callee
),
preds,
- null, null
+ TaintSet.factory() // no taints for in-context edges
);
rg.addRefEdge( hrnSrcCallee,
reCaller.getType(),
reCaller.getField(),
null,
+ null,
outOfCalleeContext,
outOfCallerContext
);
oocHrnIdOoc2callee
),
preds,
- null, null
+ toCalleeContext( reCaller.getTaints(),
+ preds )
)
);
)
);
+ oocEdgeExisting.setTaints( Canonical.unionORpreds( oocEdgeExisting.getTaints(),
+ toCalleeContext( reCaller.getTaints(),
+ preds
+ )
+ )
+ );
+
HeapRegionNode hrnCalleeAndOutContext =
(HeapRegionNode) oocEdgeExisting.getSrc();
hrnCalleeAndOutContext.setAlpha( Canonical.unionORpreds( hrnCalleeAndOutContext.getAlpha(),
Hashtable<RefEdge, ExistPredSet> calleeEdgesSatisfied =
new Hashtable<RefEdge, ExistPredSet>();
- Hashtable<ReachState, ExistPredSet> calleeStatesSatisfied =
- new Hashtable<ReachState, ExistPredSet>();
+ Hashtable< HeapRegionNode, Hashtable<ReachState, ExistPredSet> >
+ calleeNode2calleeStatesSatisfied =
+ new Hashtable< HeapRegionNode, Hashtable<ReachState, ExistPredSet> >();
+
+ Hashtable< RefEdge, Hashtable<ReachState, ExistPredSet> >
+ calleeEdge2calleeStatesSatisfied =
+ new Hashtable< RefEdge, Hashtable<ReachState, ExistPredSet> >();
+
+ Hashtable< RefEdge, Hashtable<Taint, ExistPredSet> >
+ calleeEdge2calleeTaintsSatisfied =
+ new Hashtable< RefEdge, Hashtable<Taint, ExistPredSet> >();
Hashtable< RefEdge, Set<RefSrcNode> > calleeEdges2oocCallerSrcMatches =
new Hashtable< RefEdge, Set<RefSrcNode> >();
+
Iterator meItr = rgCallee.id2hrn.entrySet().iterator();
while( meItr.hasNext() ) {
Map.Entry me = (Map.Entry) meItr.next();
// since the node is coming over, find out which reach
// states on it should come over, too
+ assert calleeNode2calleeStatesSatisfied.get( hrnCallee ) == null;
+
Iterator<ReachState> stateItr = hrnCallee.getAlpha().iterator();
while( stateItr.hasNext() ) {
ReachState stateCallee = stateItr.next();
stateCallee.getPreds().isSatisfiedBy( this,
callerNodeIDsCopiedToCallee
);
- if( predsIfSatis != null ) {
- ExistPredSet predsAlready = calleeStatesSatisfied.get( stateCallee );
- if( predsAlready == null ) {
- calleeStatesSatisfied.put( stateCallee, predsIfSatis );
- } else {
- calleeStatesSatisfied.put( stateCallee,
- Canonical.join( predsIfSatis,
- predsAlready
- )
- );
+ if( predsIfSatis != null ) {
+
+ Hashtable<ReachState, ExistPredSet> calleeStatesSatisfied =
+ calleeNode2calleeStatesSatisfied.get( hrnCallee );
+
+ if( calleeStatesSatisfied == null ) {
+ calleeStatesSatisfied =
+ new Hashtable<ReachState, ExistPredSet>();
+
+ calleeNode2calleeStatesSatisfied.put( hrnCallee, calleeStatesSatisfied );
}
+
+ calleeStatesSatisfied.put( stateCallee, predsIfSatis );
}
}
// since the edge is coming over, find out which reach
// states on it should come over, too
+ assert calleeEdge2calleeStatesSatisfied.get( reCallee ) == null;
+
stateItr = reCallee.getBeta().iterator();
while( stateItr.hasNext() ) {
ReachState stateCallee = stateItr.next();
callerNodeIDsCopiedToCallee
);
if( predsIfSatis != null ) {
- ExistPredSet predsAlready = calleeStatesSatisfied.get( stateCallee );
- if( predsAlready == null ) {
- calleeStatesSatisfied.put( stateCallee, predsIfSatis );
- } else {
- calleeStatesSatisfied.put( stateCallee,
- Canonical.join( predsIfSatis,
- predsAlready
- )
- );
+
+ Hashtable<ReachState, ExistPredSet> calleeStatesSatisfied =
+ calleeEdge2calleeStatesSatisfied.get( reCallee );
+
+ if( calleeStatesSatisfied == null ) {
+ calleeStatesSatisfied =
+ new Hashtable<ReachState, ExistPredSet>();
+
+ calleeEdge2calleeStatesSatisfied.put( reCallee, calleeStatesSatisfied );
+ }
+
+ calleeStatesSatisfied.put( stateCallee, predsIfSatis );
+ }
+ }
+
+ // since the edge is coming over, find out which taints
+ // on it should come over, too
+ assert calleeEdge2calleeTaintsSatisfied.get( reCallee ) == null;
+
+ Iterator<Taint> tItr = reCallee.getTaints().iterator();
+ while( tItr.hasNext() ) {
+ Taint tCallee = tItr.next();
+
+ predsIfSatis =
+ tCallee.getPreds().isSatisfiedBy( this,
+ callerNodeIDsCopiedToCallee
+ );
+ if( predsIfSatis != null ) {
+
+ Hashtable<Taint, ExistPredSet> calleeTaintsSatisfied =
+ calleeEdge2calleeTaintsSatisfied.get( reCallee );
+
+ if( calleeTaintsSatisfied == null ) {
+ calleeTaintsSatisfied =
+ new Hashtable<Taint, ExistPredSet>();
+
+ calleeEdge2calleeTaintsSatisfied.put( reCallee, calleeTaintsSatisfied );
}
+
+ calleeTaintsSatisfied.put( tCallee, predsIfSatis );
}
}
}
hrnCallee.getType(), // type
hrnCallee.getAllocSite(), // allocation site
toCallerContext( hrnCallee.getInherent(),
- calleeStatesSatisfied ), // inherent reach
+ calleeNode2calleeStatesSatisfied.get( hrnCallee ) ), // inherent reach
null, // current reach
predsEmpty, // predicates
hrnCallee.getDescription() // description
}
hrnCaller.setAlpha( toCallerContext( hrnCallee.getAlpha(),
- calleeStatesSatisfied
+ calleeNode2calleeStatesSatisfied.get( hrnCallee )
)
);
reCallee.getType(),
reCallee.getField(),
toCallerContext( reCallee.getBeta(),
- calleeStatesSatisfied ),
+ calleeEdge2calleeStatesSatisfied.get( reCallee ) ),
preds,
- null, null
+ toCallerContext( reCallee.getTaints(),
+ calleeEdge2calleeTaintsSatisfied.get( reCallee ) )
);
ChangeSet cs = ChangeSet.factory();
);
}
}
-
- // look to see if an edge with same field exists
- // and merge with it, otherwise just add the edge
- RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller,
- reCallee.getType(),
- reCallee.getField()
- );
- if( edgeExisting != null ) {
- edgeExisting.setBeta(
- Canonical.unionORpreds( edgeExisting.getBeta(),
- reCaller.getBeta()
- )
- );
- edgeExisting.setPreds(
- Canonical.join( edgeExisting.getPreds(),
- reCaller.getPreds()
- )
- );
-
- // for reach propagation
- if( !cs.isEmpty() ) {
+ // we're just going to use the convenient "merge-if-exists"
+ // edge call below, but still take a separate look if there
+ // is an existing caller edge to build change sets properly
+ if( !cs.isEmpty() ) {
+ RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller,
+ reCallee.getType(),
+ reCallee.getField()
+ );
+ if( edgeExisting != null ) {
ChangeSet csExisting = edgePlannedChanges.get( edgeExisting );
if( csExisting == null ) {
csExisting = ChangeSet.factory();
Canonical.union( csExisting,
cs
)
- );
- }
-
- } else {
- addRefEdge( rsnCaller, hrnDstCaller, reCaller );
-
- // for reach propagation
- if( !cs.isEmpty() ) {
+ );
+ } else {
edgesForPropagation.add( reCaller );
assert !edgePlannedChanges.containsKey( reCaller );
- edgePlannedChanges.put( reCaller, cs );
+ edgePlannedChanges.put( reCaller, cs );
}
}
+
+ // then add new caller edge or merge
+ addEdgeOrMergeWithExisting( reCaller );
}
}
mergeNodes ( rg );
mergeRefEdges ( rg );
mergeAllocSites( rg );
+ mergeAccessibleSet( rg );
}
protected void mergeNodes( ReachGraph rg ) {
edgeA.getPreds()
)
);
- edgeToMerge.setParamTaints(
- Canonical.union( edgeToMerge.getParamTaints(),
- edgeA.getParamTaints()
- )
- );
- edgeToMerge.setRblockTaints(
- Canonical.union( edgeToMerge.getRblockTaints(),
- edgeA.getRblockTaints()
- )
- );
+ edgeToMerge.setTaints(
+ Canonical.union( edgeToMerge.getTaints(),
+ edgeA.getTaints()
+ )
+ );
}
}
}
edgeA.getPreds()
)
);
- edgeToMerge.setParamTaints(
- Canonical.union( edgeToMerge.getParamTaints(),
- edgeA.getParamTaints()
- )
- );
- edgeToMerge.setRblockTaints(
- Canonical.union( edgeToMerge.getRblockTaints(),
- edgeA.getRblockTaints()
- )
- );
+ edgeToMerge.setTaints(
+ Canonical.union( edgeToMerge.getTaints(),
+ edgeA.getTaints()
+ )
+ );
}
}
}
protected void mergeAllocSites( ReachGraph rg ) {
allocSites.addAll( rg.allocSites );
}
+
+ protected void mergeAccessibleSet( ReachGraph rg ){
+ // inaccesible status is prior to accessible status
+
+ Set<TempDescriptor> varsToMerge=rg.getAccessibleVar();
+ Set<TempDescriptor> varsRemoved=new HashSet<TempDescriptor>();
+
+ for (Iterator iterator = accessibleVars.iterator(); iterator.hasNext();) {
+ TempDescriptor accessibleVar = (TempDescriptor) iterator.next();
+ if(!varsToMerge.contains(accessibleVar)){
+ varsRemoved.add(accessibleVar);
+ }
+ }
+
+ accessibleVars.removeAll(varsRemoved);
+
+ }
}
return false;
}
+
+ if( !accessibleVars.equals( rg.accessibleVars) ){
+ return false;
+ }
// if everything is equal up to this point,
// assert that allocSites is also equal--
}
return common;
+ }
+
+ public void addAccessibleVar(TempDescriptor td){
+ accessibleVars.add(td);
+ }
+
+ public Set<TempDescriptor> getAccessibleVar(){
+ return accessibleVars;
+ }
+
+ public void clearAccessibleVarSet(){
+ accessibleVars.clear();
}
+
}