--- /dev/null
+package Analysis.Disjoint;
+
+import java.util.*;
+import java.io.*;
+
+import IR.*;
+import IR.Flat.*;
+
+//////////////////////////////////////////////
+//
+// BuildStateMachines builds a state machine
+// for every task/stall site and variable pair
+//
+// StateMachineForEffects describes an intial
+// state and the effect transtions a DFJ
+// traverser should make from the current state
+// when searching for possible runtime conflicts.
+//
+//////////////////////////////////////////////
+
+public class BuildStateMachines {
+
+ protected
+ Hashtable< FlatNode, Hashtable<TempDescriptor, StateMachineForEffects> >
+ fn2var2smfe;
+
+ public BuildStateMachines() {
+ fn2var2smfe = new
+ Hashtable< FlatNode, Hashtable<TempDescriptor, StateMachineForEffects> >();
+ }
+
+ protected StateMachineForEffects getStateMachine( FlatNode fn,
+ TempDescriptor var ) {
+
+ Hashtable<TempDescriptor, StateMachineForEffects> var2smfe = fn2var2smfe.get( fn );
+ if( var2smfe == null ) {
+ var2smfe = new Hashtable<TempDescriptor, StateMachineForEffects>();
+ fn2var2smfe.put( fn, var2smfe );
+ }
+
+ StateMachineForEffects smfe = var2smfe.get( var );
+ if( smfe == null ) {
+ smfe = new StateMachineForEffects( fn );
+ var2smfe.put( var, smfe );
+ }
+
+ return smfe;
+ }
+
+
+
+ public void addToStateMachine( Taint t,
+ Effect e,
+ FlatNode currentProgramPoint ) {
+
+ FlatNode taskOrStallSite;
+ if( t.isStallSiteTaint() ) {
+ taskOrStallSite = t.getStallSite();
+ } else {
+ taskOrStallSite = t.getSESE();
+ }
+
+ TempDescriptor var = t.getVar();
+
+ StateMachineForEffects smfe = getStateMachine( taskOrStallSite, var );
+
+ FlatNode whereDefined = t.getWhereDefined();
+
+ smfe.addEffect( whereDefined, e );
+
+ // reads of pointers make a transition
+ if( e.getType() == Effect.read &&
+ e.getField().getType().isPtr() ) {
+
+ smfe.addTransition( whereDefined,
+ currentProgramPoint,
+ e );
+ }
+ }
+}
protected boolean doEffectsAnalysis = false;
protected EffectsAnalysis effectsAnalysis;
+ protected BuildStateMachines buildStateMachines;
+
// data structure for public interface
private Hashtable< Descriptor, HashSet<AllocSite> >
effectsAnalysis = new EffectsAnalysis();
}
+ if( state.RCR ) {
+ buildStateMachines = new BuildStateMachines();
+ }
+
this.allocationDepth = state.DISJOINTALLOCDEPTH;
this.releaseMode = state.DISJOINTRELEASEMODE;
this.determinismDesired = state.DISJOINTDETERMINISM;
ReachGraph.typeUtil = typeUtil;
ReachGraph.state = state;
-
ReachGraph.debugCallSiteVisitStartCapture
= state.DISJOINTDEBUGCALLVISITTOSTART;
ReachGraph.debugCallSiteVisitCounter
= 0; // count visits from 1, is incremented before first visit
+
+ EffectsAnalysis.state = state;
+ EffectsAnalysis.buildStateMachines = buildStateMachines;
+
+
if( suppressOutput ) {
System.out.println( "* Running disjoint reachability analysis with output suppressed! *" );
}
// after transfer, use updated graph to
// do effects analysis
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld );
+ effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fld, fn );
}
break;
// use transformed graph to do effects analysis
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, strongUpdate );
+ effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fld, fn, strongUpdate );
}
break;
// use transformed graph to do effects analysis
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement );
+ effectsAnalysis.analyzeFlatFieldNode( rg, rhs, fdElement, fn );
}
break;
// use transformed graph to do effects analysis
if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
- effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement,
+ effectsAnalysis.analyzeFlatSetFieldNode( rg, lhs, fdElement, fn,
false );
}
break;
import java.util.Map.Entry;
import java.io.*;
-import IR.FieldDescriptor;
-import IR.Flat.FlatCall;
-import IR.Flat.FlatMethod;
-import IR.Flat.FlatNode;
-import IR.Flat.TempDescriptor;
-import IR.Flat.FlatSESEEnterNode;
+import IR.*;
+import IR.Flat.*;
/////////////////////////////////////////////
//
private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
private Hashtable<FlatNode, Hashtable<Taint, Set<Effect>> > stallSite2te;
+ public static State state;
+ public static BuildStateMachines buildStateMachines;
+
public EffectsAnalysis() {
taint2effects = new Hashtable<Taint, Set<Effect>>();
return taint2effects.entrySet().iterator();
}
- protected void add(Taint t, Effect e) {
+ protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
Taint tNoPreds = Canonical.changePredsTo( t,
ReachGraph.predsEmpty
);
+ if( state.RCR ) {
+ buildStateMachines.addToStateMachine( t, e, currentProgramPoint );
+ }
+
// add to the global bag
Set<Effect> effectSet = taint2effects.get(tNoPreds);
if (effectSet == null) {
- public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
+ public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld, FlatNode currentProgramPoint) {
VariableNode vn = rg.td2vn.get(rhs);
if( vn == null ) {
for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
Taint taint = taintSetIter.next();
- add(taint, effect);
+ add(taint, effect, currentProgramPoint);
}
}
}
- public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
+ public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, FlatNode currentProgramPoint, boolean strongUpdate) {
VariableNode vn = rg.td2vn.get(lhs);
if( vn == null ) {
for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
Taint taint = taintSetIter.next();
- add( taint, effect );
+ add( taint, effect, currentProgramPoint );
if (strongUpdate) {
- add( taint, effectSU );
+ add( taint, effectSU, currentProgramPoint );
}
}
}
s += "\"];";
// then each transition is an edge
- Iterator<Effect> eItr = e2states.entrySet().iterator();
+ Iterator<Effect> eItr = e2states.keySet().iterator();
while( eItr.hasNext() ) {
- Effect e = eItr.next();
- SMFEState state = e2states.get( e );
+ Effect e = eItr.next();
+ Set<SMFEState> states = e2states.get( e );
- s += "\n "+
- id.nodeid+" -> "+state.id.nodeid+
- "[label=\""+e+"\"];"
+ Iterator<SMFEState> sItr = states.iterator();
+ while( sItr.hasNext() ) {
+ SMFEState state = sItr.next();
+
+ s += "\n "+
+ id.nodeid+" -> "+state.id.nodeid+
+ "[label=\""+e+"\"];";
+ }
}
return s;
initialState = getState( fnInitial );
}
+ public void addEffect( FlatNode fnState,
+ Effect e ) {
+
+ assert fn2state.containsKey( fnState );
+ SMFEState state = getState( fnState );
+ state.addEffect( e );
+ }
+
public void addTransition( FlatNode fnFrom,
FlatNode fnTo,
Effect e ) {
protected SMFEState getState( FlatNode fn ) {
SMFEState state = fn2state.get( fn );
if( state == null ) {
- state = new SMFEState();
+ state = new SMFEState( fn );
}
return state;
}
bw.write( "digraph "+graphName+" {\n" );
- Iterator<Effect> fnItr = fn2state.entrySet().iterator();
+ Iterator<FlatNode> fnItr = fn2state.keySet().iterator();
while( fnItr.hasNext() ) {
SMFEState state = fn2state.get( fnItr.next() );
bw.write( state.toStringDOT()+"\n" );