// get successive captures of the analysis state
boolean takeDebugSnapshots = false;
- String descSymbolDebug = "addSomething";
+ String descSymbolDebug = "MDRunner";
boolean stopAfterCapture = true;
// increments every visit to debugSnapshot, don't fiddle with it
int numStartCountReport = 0;
// the frequency of debugCounter values to print out, 0 no report
- int freqCountReport = 0;
+ int freqCountReport = 50;
// the debugCounter value at which to start taking snapshots
- int iterStartCapture = 25;
+ int iterStartCapture = 350;
// the number of snapshots to take
- int numIterToCapture = 300;
+ int numIterToCapture = 400;
void debugSnapshot( ReachGraph rg, FlatNode fn, boolean in ) {
if( debugCounter > numStartCountReport &&
freqCountReport > 0 &&
- debugCounter % freqCountReport == 0
+ debugCounter % freqCountReport == 0 &&
+ in
) {
System.out.println( " @@@ debug counter = "+
debugCounter );
if( debugCounter > iterStartCapture ) {
System.out.println( " @@@ capturing debug "+
- (debugCounter - iterStartCapture)+
+ (debugCounter /*- iterStartCapture*/)+
" @@@" );
String graphName;
if( in ) {
graphName = String.format( "snap%04din",
- debugCounter - iterStartCapture );
+ debugCounter ); //- iterStartCapture );
} else {
graphName = String.format( "snap%04dout",
- debugCounter - iterStartCapture );
+ debugCounter ); //- iterStartCapture );
}
if( fn != null ) {
graphName = graphName + fn;
--- /dev/null
+package Analysis.Disjoint;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+// a heap region node has an integer ID, but heap regions can
+// also have reach tuples with the same ID but out-of-context
+// so 17 and 17? mean something different in reachability states
+public class HrnIdOoc {
+ protected Integer id;
+ protected Boolean ooc;
+
+ public HrnIdOoc( Integer id, Boolean ooc ) {
+ this.id = id;
+ this.ooc = ooc;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public Boolean getOoc() {
+ return ooc;
+ }
+
+ public boolean equals( Object o ) {
+ if( o == null ) {
+ return false;
+ }
+
+ if( !(o instanceof HrnIdOoc) ) {
+ return false;
+ }
+
+ HrnIdOoc hio = (HrnIdOoc) o;
+
+ return
+ id.equals( hio.id ) &&
+ ooc.equals( hio.ooc );
+ }
+
+ public int hashCode() {
+ int hash = id.intValue();
+ if( ooc.booleanValue() ) {
+ hash = ~hash;
+ }
+ return hash;
+ }
+
+ public String toString() {
+ String s = id.toString();
+
+ if( ooc ) {
+ s += "?";
+ }
+
+ return s;
+ }
+}
// 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,
- Set<ReachTuple> oocTuples
+ protected ReachSet toCalleeContext( ReachSet rs,
+ ExistPredSet preds,
+ Set<HrnIdOoc> oocHrnIdOoc2callee
) {
ReachSet out = ReachSet.factory();
// only translate this tuple if it is
// in the out-callee-context bag
- if( !oocTuples.contains( rt ) ) {
+ HrnIdOoc hio = new HrnIdOoc( rt.getHrnID(),
+ rt.isOutOfContext()
+ );
+ if( !oocHrnIdOoc2callee.contains( hio ) ) {
stateNew = Canonical.add( stateNew, rt );
continue;
}
} // end iterating over parameters as starting points
- // now collect out-of-context reach tuples and
- // more out-of-context edges
- Set<ReachTuple> oocTuples = new HashSet<ReachTuple>();
+ // now collect out-of-callee-context IDs and
+ // map them to whether the ID is out of the caller
+ // context as well
+ Set<HrnIdOoc> oocHrnIdOoc2callee = new HashSet<HrnIdOoc>();
Iterator<Integer> itrInContext =
callerNodeIDsCopiedToCallee.iterator();
while( rtItr.hasNext() ) {
ReachTuple rt = rtItr.next();
- oocTuples.add( rt );
+ oocHrnIdOoc2callee.add( new HrnIdOoc( rt.getHrnID(),
+ rt.isOutOfContext()
+ )
+ );
}
}
}
}
-
// the callee view is a new graph: DON'T MODIFY *THIS* graph
ReachGraph rg = new ReachGraph();
hrnCaller.getAllocSite(),
toCalleeContext( hrnCaller.getInherent(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
toCalleeContext( hrnCaller.getAlpha(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds,
hrnCaller.getDescription()
reArg.getField(),
toCalleeContext( reArg.getBeta(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds
);
reCaller.getField(),
toCalleeContext( reCaller.getBeta(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds
);
null, // alloc site, shouldn't be used
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds,
"out-of-context"
null, // alloc site, shouldn't be used
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds,
"out-of-context"
);
+
} else {
// otherwise it is there, so merge reachability
hrnCalleeAndOutContext.setAlpha( Canonical.unionORpreds( hrnCalleeAndOutContext.getAlpha(),
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
)
)
);
}
}
+ assert hrnCalleeAndOutContext.reachHasOnlyOOC();
+
rg.addRefEdge( hrnCalleeAndOutContext,
hrnDstCallee,
new RefEdge( hrnCalleeAndOutContext,
reCaller.getField(),
toCalleeContext( reCaller.getBeta(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
),
preds
)
oocEdgeExisting.setBeta( Canonical.unionORpreds( oocEdgeExisting.getBeta(),
toCalleeContext( reCaller.getBeta(),
preds,
- oocTuples
+ oocHrnIdOoc2callee
)
)
);
hrnCalleeAndOutContext.setAlpha( Canonical.unionORpreds( hrnCalleeAndOutContext.getAlpha(),
toCalleeContext( oocReach,
preds,
- oocTuples
+ oocHrnIdOoc2callee
)
)
);
-
+ assert hrnCalleeAndOutContext.reachHasOnlyOOC();
}
}
assert rsetEmpty.equals( edge.getBetaNew() );
}
- // calculate boldB for this flagged node, or out-of-context node
+ // make a mapping of IDs to heap regions they propagate from
if( hrn.isFlagged() ) {
assert !hrn.isOutOfContext();
assert !icID2srcs.containsKey( hrn.getID() );
+
+ // in-context flagged node IDs simply propagate from the
+ // node they name
Set<HeapRegionNode> srcs = new HashSet<HeapRegionNode>();
srcs.add( hrn );
icID2srcs.put( hrn.getID(), srcs );
if( hrn.isOutOfContext() ) {
assert !hrn.isFlagged();
+ // the reachability states on an out-of-context
+ // node are not really important (combinations of
+ // IDs or arity)--what matters is that the states
+ // specify which nodes this out-of-context node
+ // stands in for. For example, if the state [17?, 19*]
+ // appears on the ooc node, it may serve as a source
+ // for node 17? and a source for node 19.
Iterator<ReachState> stateItr = hrn.getAlpha().iterator();
while( stateItr.hasNext() ) {
ReachState state = stateItr.next();