}
+ public static ReachState attach( ReachState rs,
+ ExistPredSet preds ) {
+ assert rs != null;
+ assert preds != null;
+ assert rs.isCanonical();
+ assert preds.isCanonical();
+
+ CanonicalOp op =
+ new CanonicalOp( CanonicalOp.REACHSTATE_ATTACH_EXISTPREDSET,
+ rs,
+ preds );
+
+ Canonical result = op2result.get( op );
+ if( result != null ) {
+ return (ReachState) result;
+ }
+
+ // otherwise, no cached result...
+ ReachState out = new ReachState();
+ out.reachTuples.addAll( rs.reachTuples );
+ out.preds = Canonical.join( rs.preds,
+ preds );
+
+ out = (ReachState) makeCanonical( out );
+ op2result.put( op, out );
+ return out;
+ }
+
+
public static ReachState union( ReachState rs1,
ReachState rs2 ) {
assert rs1 != null;
ReachState out = new ReachState();
out.reachTuples.addAll( rs1.reachTuples );
out.reachTuples.addAll( rs2.reachTuples );
+ out.preds = Canonical.join( rs1.getPreds(),
+ rs2.getPreds()
+ );
out = (ReachState) makeCanonical( out );
op2result.put( op, out );
ReachState out = new ReachState();
out.reachTuples.addAll( rs.reachTuples );
out.reachTuples.add( rt );
+ out.preds = rs.preds;
out = (ReachState) makeCanonical( out );
op2result.put( op, out );
out.reachTuples.add( rto );
}
}
+
+ out.preds = Canonical.join( rs1.getPreds(),
+ rs2.getPreds()
+ );
out = (ReachState) makeCanonical( out );
op2result.put( op, out );
ReachState out = new ReachState();
out.reachTuples.addAll( rs.reachTuples );
out.reachTuples.remove( rt );
+ out.preds = rs.preds;
out = (ReachState) makeCanonical( out );
op2result.put( op, out );
);
}
+ out.preds = rs.preds;
+
out = (ReachState) makeCanonical( out );
op2result.put( op, out );
return out;
}
-
+ /*
public static ReachSet toCalleeContext( ReachSet rs,
AllocSite as ) {
assert rs != null;
op2result.put( op, out );
return out;
}
+ */
public static ReachState toCalleeContext( ReachState state,
AllocSite as ) {
}
}
+ out = Canonical.attach( out,
+ state.getPreds()
+ );
+
assert out.isCanonical();
op2result.put( op, out );
return out;
}
}
+ out = Canonical.attach( out,
+ state.getPreds()
+ );
+
assert out.isCanonical();
op2result.put( op, out );
return out;
// used below to convert a ReachSet to its callee-context
// equivalent with respect to allocation sites in this graph
- protected ReachSet toCalleeContext( ReachSet rs ) {
- ReachSet out = rs;
- Iterator<AllocSite> asItr = allocSites.iterator();
- while( asItr.hasNext() ) {
- AllocSite as = asItr.next();
- out = Canonical.toCalleeContext( out, as );
+ protected ReachSet toCalleeContext( ReachSet rs,
+ Integer hrnID,
+ TempDescriptor tdSrc,
+ Integer hrnSrcID,
+ Integer hrnDstID,
+ TypeDescriptor type,
+ String field,
+ boolean outOfContext
+ ) {
+ ReachSet out = ReachSet.factory();
+
+ Iterator<ReachState> itr = rs.iterator();
+ while( itr.hasNext() ) {
+ ReachState stateCaller = itr.next();
+
+ ReachState stateCallee = stateCaller;
+
+ Iterator<AllocSite> asItr = allocSites.iterator();
+ while( asItr.hasNext() ) {
+ AllocSite as = asItr.next();
+
+ stateCallee = Canonical.toCalleeContext( stateCallee, as );
+ }
+
+ ExistPredSet preds;
+
+ if( outOfContext ) {
+ preds = predsEmpty;
+ } else {
+ ExistPred pred;
+ if( hrnID != null ) {
+ assert tdSrc == null;
+ assert hrnSrcID == null;
+ assert hrnDstID == null;
+ pred = ExistPred.factory( hrnID,
+ stateCaller );
+ } else {
+ assert tdSrc != null || hrnSrcID != null;
+ assert hrnDstID != null;
+ pred = ExistPred.factory( tdSrc,
+ hrnSrcID,
+ hrnDstID,
+ type,
+ field,
+ stateCaller,
+ false );
+ }
+ preds = ExistPredSet.factory( pred );
+ }
+
+ stateCallee = Canonical.attach( stateCallee,
+ preds );
+
+ out = Canonical.add( out,
+ stateCallee
+ );
+
}
assert out.isCanonical();
return out;
false, // out-of-context?
hrnSrcCaller.getType(),
hrnSrcCaller.getAllocSite(),
- toCalleeContext( hrnSrcCaller.getInherent() ),
- toCalleeContext( hrnSrcCaller.getAlpha() ),
+ toCalleeContext( hrnSrcCaller.getInherent(), // in state
+ hrnSrcCaller.getID(), // node pred
+ null, null, null, null, null, // edge pred
+ false ), // ooc pred
+ toCalleeContext( hrnSrcCaller.getAlpha(), // in state
+ hrnSrcCaller.getID(), // node pred
+ null, null, null, null, null, // edge pred
+ false ), // ooc pred
preds,
hrnSrcCaller.getDescription()
);
false, // out-of-context?
hrnCaller.getType(),
hrnCaller.getAllocSite(),
- toCalleeContext( hrnCaller.getInherent() ),
- toCalleeContext( hrnCaller.getAlpha() ),
+ toCalleeContext( hrnCaller.getInherent(), // in state
+ hrnDstID, // node pred
+ null, null, null, null, null, // edge pred
+ false ), // ooc pred
+ toCalleeContext( hrnCaller.getAlpha(), // in state
+ hrnDstID, // node pred
+ null, null, null, null, null, // edge pred
+ false ), // ooc pred
preds,
hrnCaller.getDescription()
);
hrnCallee,
reCaller.getType(),
reCaller.getField(),
- toCalleeContext( reCaller.getBeta() ),
+ toCalleeContext( reCaller.getBeta(), // in state
+ null, // node pred
+ tdSrc, // edge pred
+ hrnSrcID, // edge pred
+ hrnDstID, // edge pred
+ reCaller.getType(), // edge pred
+ reCaller.getField(), // edge pred
+ false ), // ooc pred
preds
)
);
true, // out-of-context?
oocNodeType,
null, // alloc site, shouldn't be used
- toCalleeContext( oocReach ), // inherent
- toCalleeContext( oocReach ), // alpha
+ toCalleeContext( oocReach, // in state
+ null, // node pred
+ null, null, null, null, null, // edge pred
+ true // ooc pred
+ ), // inherent
+ toCalleeContext( oocReach, // in state
+ null, // node pred
+ null, null, null, null, null, // edge pred
+ true // ooc pred
+ ), // alpha
preds,
"out-of-context"
);
true, // out-of-context?
oocNodeType,
null, // alloc site, shouldn't be used
- toCalleeContext( oocReach ), // inherent
- toCalleeContext( oocReach ), // alpha
+ toCalleeContext( oocReach, // in state
+ null, // node pred
+ null, null, null, null, null, // edge pred
+ true // ooc pred
+ ), // inherent
+ toCalleeContext( oocReach, // in state
+ null, // node pred
+ null, null, null, null, null, // edge pred
+ true // ooc pred
+ ), // alpha
preds,
"out-of-context"
);
hrnCalleeAndInContext,
edgeMightCross.getType(),
edgeMightCross.getField(),
- toCalleeContext( edgeMightCross.getBeta() ),
+ toCalleeContext( edgeMightCross.getBeta(), // in state
+ null, // node pred
+ oocPredSrcTemp, // edge pred
+ oocPredSrcID, // edge pred
+ hrnCallerAndInContext.getID(), // edge pred
+ edgeMightCross.getType(), // edge pred
+ edgeMightCross.getField(), // edge pred
+ false // ooc pred
+ ),
preds
)
);
} else {
// the out-of-context edge already exists
oocEdgeExisting.setBeta( Canonical.union( oocEdgeExisting.getBeta(),
- toCalleeContext( edgeMightCross.getBeta() )
+ toCalleeContext( edgeMightCross.getBeta(), // in state
+ null, // node pred
+ oocPredSrcTemp, // edge pred
+ oocPredSrcID, // edge pred
+ hrnCallerAndInContext.getID(), // edge pred
+ edgeMightCross.getType(), // edge pred
+ edgeMightCross.getField(), // edge pred
+ false // ooc pred
+ )
)
);
-
+
oocEdgeExisting.setPreds( Canonical.join( oocEdgeExisting.getPreds(),
edgeMightCross.getPreds()
)