public int allocationDepth;
protected boolean doEffectsAnalysis = false;
-
+ protected EffectsAnalysis effectsAnalysis;
// data structure for public interface
private Hashtable< Descriptor, HashSet<AllocSite> >
if( rblockRel != null ) {
doEffectsAnalysis = true;
+ effectsAnalysis = new EffectsAnalysis();
}
this.allocationDepth = state.DISJOINTALLOCDEPTH;
} catch( IOException e ) {
throw new Error( "IO Exception while writing disjointness analysis output." );
}
+
+ if( doEffectsAnalysis ) {
+ effectsAnalysis.writeEffectsPerMethod( "effects-per-method.txt" );
+ }
}
fld = ffn.getField();
if( shouldAnalysisTrack( fld.getType() ) ) {
rg.assignTempXEqualToTempYFieldF( lhs, rhs, fld );
+
+ if( doEffectsAnalysis ) {
+ effectsAnalysis.analyzeFlatFieldNode( fmContaining, rg, rhs, fld );
+ }
}
break;
lhs = fsfn.getDst();
fld = fsfn.getField();
rhs = fsfn.getSrc();
+
if( shouldAnalysisTrack( fld.getType() ) ) {
- rg.assignTempXFieldFEqualToTempY( lhs, fld, rhs );
+ boolean strongUpdate = rg.assignTempXFieldFEqualToTempY( lhs, fld, rhs );
+
+ if( doEffectsAnalysis ) {
+ effectsAnalysis.analyzeFlatSetFieldNode( fmContaining, rg, lhs, fld, strongUpdate );
+ }
}
break;
}
-
// the transformation for a call site should update the
// current heap abstraction with any effects from the callee,
// or if the method is virtual, the effects from any possible
} else {
+ // calculate the method call transform
+
+ Hashtable<Taint, TaintSet> tCallee2tsCaller = null;
+
+ if( doEffectsAnalysis ) {
+ tCallee2tsCaller = new Hashtable<Taint, TaintSet>();
+ }
+
rgCopy.resolveMethodCall( fc,
fmPossible,
rgEffect,
callerNodeIDsCopiedToCallee,
+ tCallee2tsCaller,
writeDebugDOTs
);
+
+ if( doEffectsAnalysis ) {
+ effectsAnalysis.analyzeFlatCall( fmContaining,
+ fmPossible,
+ tCallee2tsCaller );
+ }
}
- rgMergeOfEffects.merge( rgCopy );
+ rgMergeOfEffects.merge( rgCopy );
}
package Analysis.Disjoint;
-import Analysis.OwnershipAnalysis.EffectsKey;
import IR.FieldDescriptor;
import IR.Flat.TempDescriptor;
public static final int write = 2;
public static final int strongupdate = 3;
- // identify a parameter index
- protected Integer paramIndex;
-
- // identify an inset var
- protected TempDescriptor insetVar;
-
- // identify an allocation site of inset var
- protected AllocSite insetAllocSite;
-
// identify an allocation site of affected object
protected AllocSite affectedAllocSite;
// identify a field
protected FieldDescriptor field;
- public Effect(Integer pi, AllocSite insetAS, AllocSite affectedAS, int type, FieldDescriptor field) {
- this.paramIndex = pi;
- this.insetAllocSite = insetAS;
+ public Effect(AllocSite affectedAS, int type, FieldDescriptor field) {
this.affectedAllocSite = affectedAS;
this.type = type;
this.field = field;
}
- public Integer getParamIndex() {
- return paramIndex;
- }
-
- public void setParamIndex(Integer paramIndex) {
- this.paramIndex = paramIndex;
- }
-
- public TempDescriptor getInsetVar() {
- return insetVar;
- }
-
- public void setInsetVar(TempDescriptor insetVar) {
- this.insetVar = insetVar;
- }
-
- public AllocSite getInsetAllocSite() {
- return insetAllocSite;
- }
-
- public void setInsetAllocSite(AllocSite insetAllocSite) {
- this.insetAllocSite = insetAllocSite;
- }
-
public AllocSite getAffectedAllocSite() {
return affectedAllocSite;
}
}
Effect in = (Effect) o;
-
- if (paramIndex != null) {
- if (!paramIndex.equals(in.getParamIndex())) {
- return false;
- }
- } else {
- if (!insetVar.equals(in.getInsetVar())
- && !insetAllocSite.equals(in.getInsetAllocSite())) {
- return false;
- }
- }
-
+
if (affectedAllocSite.equals(in.getAffectedAllocSite())
&& type == in.getType()
&& field.equals(in.getField())) {
int hash = affectedAllocSite.hashCode();
- if (paramIndex != null) {
- hash = hash ^ paramIndex.hashCode();
- } else if (insetAllocSite != null) {
- hash = hash ^ insetAllocSite.hashCode();
- }
-
hash = hash + type;
if (field != null) {
public String toString() {
String s = "(";
- if (paramIndex != null) {
- s += "param" + paramIndex;
- } else {
- s += insetVar;
- s += ", " + insetAllocSite.toStringBrief();
- }
-
- s += ", " + affectedAllocSite.toStringBrief();
+ s += affectedAllocSite.toStringBrief();
s += ", ";
if (type == read) {
s += "read";
import java.util.HashSet;
import java.util.Hashtable;
-
+import java.util.Set;
+import java.util.Iterator;
import IR.Flat.TempDescriptor;
public class EffectSet {
- private Hashtable<Integer, HashSet<Effect>> methodEffectSet;
- private Hashtable<TempDescriptor, HashSet<Effect>> rblockEffectSet;
+ private Hashtable<Taint, HashSet<Effect>> taint2effects;
public EffectSet() {
- methodEffectSet = new Hashtable<Integer, HashSet<Effect>>();
+ taint2effects = new Hashtable<Taint, HashSet<Effect>>();
}
- public void addMethodEffect(Integer paramIdx, Effect e) {
- HashSet<Effect> effectSet = methodEffectSet.get(paramIdx);
+ public void addEffect(Taint t, Effect e) {
+ HashSet<Effect> effectSet = taint2effects.get(t);
if (effectSet == null) {
effectSet = new HashSet<Effect>();
}
effectSet.add(e);
- methodEffectSet.put(paramIdx, effectSet);
+ taint2effects.put(t, effectSet);
}
- public String toString() {
- if (methodEffectSet != null) {
- return methodEffectSet.toString();
- } else {
- return rblockEffectSet.toString();
- }
+ public Set<Effect> getEffects(Taint t) {
+ return taint2effects.get(t);
}
+ public Iterator getAllEffectPairs() {
+ return taint2effects.entrySet().iterator();
+ }
+
+ public String toString() {
+ return taint2effects.toString();
+ }
}
package Analysis.Disjoint;
-import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.*;
+import java.io.*;
import IR.FieldDescriptor;
import IR.Flat.FlatCall;
import IR.Flat.FlatMethod;
import IR.Flat.TempDescriptor;
+import IR.Flat.FlatSESEEnterNode;
/////////////////////////////////////////////
//
public class EffectsAnalysis {
- private Hashtable<FlatMethod, EffectSet> mapFlatmethodToEffectset;
+ private Hashtable<FlatMethod, EffectSet> fm2effectSet;
- // private Hashtable<MethodContext, MethodEffects>
- // mapMethodContextToMethodEffects;
- // boolean methodeffects = false;
-
- public EffectsAnalysis(boolean methodeffects) {
- mapFlatmethodToEffectset = new Hashtable<FlatMethod, EffectSet>();
+ public EffectsAnalysis() {
+ fm2effectSet = new Hashtable<FlatMethod, EffectSet>();
}
public void analyzeFlatFieldNode(FlatMethod fmContaining, ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
VariableNode vn = rg.td2vn.get(rhs);
- EffectSet effectSet = mapFlatmethodToEffectset.get(fmContaining);
- if (effectSet == null) {
- effectSet = new EffectSet();
- }
-
for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
RefEdge edge = iterator.next();
TaintSet taintSet = edge.getTaints();
for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
Taint taint = taintSetIter.next();
-// Effect effect = new Effect(taint.getParamIndex(), taint.getAllocSite(), affectedAlloc, Effect.read, fld);
-// effectSet.addMethodEffect(taint.getParamIndex(), effect);
+ EffectSet effectSet = fm2effectSet.get(fmContaining);
+ if (effectSet == null) {
+ effectSet = new EffectSet();
+ }
+
+ Effect effect = new Effect(affectedAlloc, Effect.read, fld);
+ effectSet.addEffect(taint, effect);
+ fm2effectSet.put(fmContaining, effectSet);
}
}
-
- mapFlatmethodToEffectset.put(fmContaining, effectSet);
-
}
- public void analyzeFlatSetFieldNode(FlatMethod fmContaining, ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld) {
+ public void analyzeFlatSetFieldNode(FlatMethod fmContaining, ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
VariableNode vn = rg.td2vn.get(lhs);
- EffectSet effectSet = mapFlatmethodToEffectset.get(fmContaining);
- if (effectSet == null) {
- effectSet = new EffectSet();
- }
-
for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
RefEdge edge = iterator.next();
TaintSet taintSet = edge.getTaints();
for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
Taint taint = taintSetIter.next();
-// Effect effect = new Effect(taint.getParamIndex(), taint.getAllocSite(), affectedAlloc, Effect.write, fld);
-// effectSet.addMethodEffect(taint.getParamIndex(), effect);
-
+ EffectSet effectSet = fm2effectSet.get(fmContaining);
+ if (effectSet == null) {
+ effectSet = new EffectSet();
+ }
+
+ Effect effect = new Effect(affectedAlloc, Effect.write, fld);
+ effectSet.addEffect(taint, effect);
+
+ if (strongUpdate) {
+ effectSet.addEffect(taint,
+ new Effect(affectedAlloc,
+ Effect.strongupdate,
+ fld)
+ );
+ }
+
+ fm2effectSet.put(fmContaining, effectSet);
}
}
+ }
- mapFlatmethodToEffectset.put(fmContaining, effectSet);
+ public void analyzeFlatCall(FlatMethod fmContaining, FlatMethod fmCallee, Hashtable<Taint, TaintSet> tCallee2tsCaller) {
+
+ EffectSet esCaller = getEffectSet(fmContaining);
+ if( esCaller == null ) {
+ esCaller = new EffectSet();
+ }
+ EffectSet esCallee = getEffectSet(fmCallee);
+ if( esCallee == null ) {
+ esCallee = new EffectSet();
+ }
+
+ Iterator meItr = esCallee.getAllEffectPairs();
+ while( meItr.hasNext() ) {
+ Map.Entry me = (Map.Entry) meItr.next();
+ Taint tCallee = (Taint) me.getKey();
+ HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
+
+ if( tCallee2tsCaller.containsKey( tCallee ) ) {
+
+ Iterator<Taint> tItr = tCallee2tsCaller.get( tCallee ).iterator();
+ while( tItr.hasNext() ) {
+ Taint tCaller = tItr.next();
+
+ Iterator<Effect> eItr = effects.iterator();
+ while( eItr.hasNext() ) {
+ Effect e = eItr.next();
+
+ esCaller.addEffect( tCaller, e );
+ }
+ }
+ }
+ }
+
+ fm2effectSet.put(fmContaining, esCaller);
}
public EffectSet getEffectSet(FlatMethod fm) {
- return mapFlatmethodToEffectset.get(fm);
+ return fm2effectSet.get(fm);
+ }
+
+ public void writeEffectsPerMethod( String outfile ) {
+ try {
+ BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
+
+ bw.write( "Effects\n\n" );
+
+ Iterator meItr1 = fm2effectSet.entrySet().iterator();
+ while( meItr1.hasNext() ) {
+ Map.Entry me1 = (Map.Entry) meItr1.next();
+ FlatMethod fm = (FlatMethod) me1.getKey();
+ EffectSet es = (EffectSet) me1.getValue();
+
+ bw.write( "\n"+fm+"\n--------------\n" );
+
+ Iterator meItr2 = es.getAllEffectPairs();
+ while( meItr2.hasNext() ) {
+ Map.Entry me2 = (Map.Entry) meItr2.next();
+ Taint taint = (Taint) me2.getKey();
+ HashSet<Effect> effects = (HashSet<Effect>) me2.getValue();
+
+ Iterator<Effect> eItr = effects.iterator();
+ while( eItr.hasNext() ) {
+ Effect e = eItr.next();
+
+ bw.write( " "+taint+"-->"+e+"\n" );
+ }
+ }
+ }
+
+ bw.close();
+ } catch( IOException e ) {}
}
/*
}
- 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,
}
- 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;
+ }
}
}
}
// 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;
}
// equivalent, just eliminate Taints with bad preds
protected TaintSet
toCallerContext( TaintSet ts,
- Hashtable<Taint, ExistPredSet> calleeTaintsSatisfied
+ Hashtable<Taint, ExistPredSet> calleeTaintsSatisfied,
+ Hashtable<Taint, TaintSet> tCallee2tsCaller
) {
+
TaintSet out = TaintSet.factory();
// when the mapping is null it means there were no
out = Canonical.add( out,
tCaller
);
+
+ // this mapping aids the effects analysis--
+ // ONLY DO IF MASTER MAP IS NOT NULL
+ if( tCallee2tsCaller != null ) {
+ TaintSet tsCaller = tCallee2tsCaller.get( tCallee );
+ if( tsCaller == null ) {
+ tsCaller = TaintSet.factory();
+ }
+ tsCaller = Canonical.add( tsCaller, tCaller );
+ tCallee2tsCaller.put( tCallee, tsCaller );
+ }
}
}
FlatMethod fmCallee,
ReachGraph rgCallee,
Set<Integer> callerNodeIDsCopiedToCallee,
+ Hashtable<Taint, TaintSet> tCallee2tsCaller,
boolean writeDebugDOTs
) {
calleeEdge2calleeStatesSatisfied.get( reCallee ) ),
preds,
toCallerContext( reCallee.getTaints(),
- calleeEdge2calleeTaintsSatisfied.get( reCallee ) )
+ calleeEdge2calleeTaintsSatisfied.get( reCallee ),
+ tCallee2tsCaller )
);
ChangeSet cs = ChangeSet.factory();
BUILDSCRIPT=~/research/Robust/src/buildscript
BSFLAGS= -mainclass Test -justanalyze -ooojava -disjoint -disjoint-k 1 -enable-assertions
-DEBUGFLAGS= -disjoint-write-dots final -disjoint-write-initial-contexts -disjoint-write-ihms -disjoint-debug-snap-method main 0 10 true
+#DEBUGFLAGS= -disjoint-write-dots final -disjoint-write-initial-contexts -disjoint-write-ihms -disjoint-debug-snap-method main 0 10 true
all: $(PROGRAM).bin
rm -f *.dot
rm -f *.png
rm -f aliases.txt
+ rm -f effects-per-method.txt
Foo b = new Foo();
/*
- if( false ) {
- a = new Foo();
+ rblock r1 {
+ a.f = new Foo();
}
*/
-
+
rblock r1 {
a.f = new Foo();
-
b.f = new Foo();
doSomething( a, b );
}
-
}
static void doSomething( Foo a, Foo b ) {