public class OwnershipGraph {
- private int allocationDepth;
- private TypeUtil typeUtil;
+ // use to disable improvements for comparison
+ protected static final boolean DISABLE_STRONG_UPDATES = false;
+ protected static final boolean DISABLE_GLOBAL_SWEEP = false;
+
+ protected static int allocationDepth = -1;
+ protected static TypeUtil typeUtil = null;
+ protected static boolean debugCallMap = false;
+ protected static int debugCallMapCount = 0;
+ protected static String debugCallee = null;
+ protected static String debugCaller = null;
// there was already one other very similar reason
// for traversing heap nodes that is no longer needed
public Hashtable<Integer, TokenTuple> paramIndex2paramTokenSecondaryStar;
- public OwnershipGraph(int allocationDepth, TypeUtil typeUtil) {
- this.allocationDepth = allocationDepth;
- this.typeUtil = typeUtil;
+ public OwnershipGraph() {
id2hrn = new Hashtable<Integer, HeapRegionNode>();
td2ln = new Hashtable<TempDescriptor, LabelNode >();
assert edge == referencee.getReferenceFrom(referencer,
type,
field);
+
+// int oldTaint=edge.getTaintIdentifier();
+// if(referencer instanceof HeapRegionNode){
+// depropagateTaintIdentifier((HeapRegionNode)referencer,oldTaint,new HashSet<HeapRegionNode>());
+// }
referencer.removeReferencee(edge);
referencee.removeReferencer(edge);
null,
false,
betaY.intersection(betaHrn) );
+
+ int newTaintIdentifier=getTaintIdentifierFromHRN(hrnHrn);
+ edgeNew.setTaintIdentifier(newTaintIdentifier);
addReferenceEdge(lnX, hrnHrn, edgeNew);
}
(hrnX.isSingleObject() && lnX.getNumReferencees() == 1) // case 2
)
) {
- strongUpdate = true;
- clearReferenceEdgesFrom( hrnX, f.getType(), f.getSymbol(), false );
+ if( !DISABLE_STRONG_UPDATES ) {
+ strongUpdate = true;
+ clearReferenceEdgesFrom( hrnX, f.getType(), f.getSymbol(), false );
+ }
}
}
edgeExisting.setBeta(
edgeExisting.getBeta().union( edgeNew.getBeta() )
);
- int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
- edgeExisting.tainedBy(newTaintIdentifier);
+ if((!hrnX.isParameter() && hrnY.isParameter()) || ( hrnX.isParameter() && hrnY.isParameter())){
+ int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
+ edgeExisting.unionTaintIdentifier(newTaintIdentifier);
+ }
// a new edge here cannot be reflexive, so existing will
// always be also not reflexive anymore
edgeExisting.setIsInitialParam( false );
} else {
- int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
- edgeNew.setTaintIdentifier(newTaintIdentifier);
- propagateTaintIdentifier(hrnX,newTaintIdentifier,new HashSet<HeapRegionNode>());
+
+ if((!hrnX.isParameter() && hrnY.isParameter()) || ( hrnX.isParameter() && hrnY.isParameter())){
+ int newTaintIdentifier=getTaintIdentifierFromHRN(hrnY);
+ edgeNew.setTaintIdentifier(newTaintIdentifier);
+ }
+ //currently, taint isn't propagated through the chain of refrences
+ //propagateTaintIdentifier(hrnX,newTaintIdentifier,new HashSet<HeapRegionNode>());
addReferenceEdge( hrnX, hrnY, edgeNew );
}
}
// if there was a strong update, make sure to improve
// reachability with a global sweep
- if( strongUpdate ) {
- globalSweep();
+ if( strongUpdate ) {
+ if( !DISABLE_GLOBAL_SWEEP ) {
+ globalSweep();
+ }
}
}
null, // match all fields
true, // special param initial
betaSoup ); // reachability
- edgeSecondaryReflexive.tainedBy(paramIndex);
addReferenceEdge( hrnSecondary, hrnSecondary, edgeSecondaryReflexive );
ReferenceEdge edgeSecondary2Primary =
null, // match all fields
true, // special param initial
betaSoup ); // reachability
- edgeSecondary2Primary.tainedBy(paramIndex);
addReferenceEdge( hrnSecondary, hrnPrimary, edgeSecondary2Primary );
ReferenceEdge edgeFromLabelR =
fd.getSymbol(), // field
true, // special param initial
betaSoup ); // reachability
- edgePrimaryReflexive.tainedBy(paramIndex);
addReferenceEdge( hrnPrimary, hrnPrimary, edgePrimaryReflexive );
}
fd.getSymbol(), // field
true, // special param initial
betaSoup ); // reachability
- edgePrimary2Secondary.tainedBy(paramIndex);
addReferenceEdge( hrnPrimary, hrnSecondary, edgePrimary2Secondary );
}
}
null, // match all fields
true, // special param initial
betaSoup ); // reachability
- edgeAliased2Primary.tainedBy(paramIndex);
addReferenceEdge( hrnAliasBlob, hrnPrimary, edgeAliased2Primary );
ReferenceEdge edgeFromLabelR =
LabelNode lnParamI = getLabelNodeFromTemp( tdParamI );
Integer idPrimaryI = paramIndex2idPrimary.get( i );
+
+ /*
+ if( idPrimaryI == null ) {
+ try {
+ writeGraph( "debugalias",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
+ } catch( Exception e ) {}
+ System.out.println( "FlatMethod="+fm+"\nalias set="+aliasedParamIndices+
+ "\nindex bad="+i);
+ }
+ */
+
assert idPrimaryI != null;
HeapRegionNode primaryI = id2hrn.get( idPrimaryI );
assert primaryI != null;
// affect reachability
TypeDescriptor typeDeref = typeI.dereference();
+
+
+ /////////////////////////////////////////////////////////////
+ // NOTE! For the KMeans benchmark a parameter of type float
+ // array, which has an immutable dereferenced type, is causing
+ // this assertion to fail. I'm commenting it out for now which
+ // is safe, because it allows aliasing where no aliasing can occur,
+ // so it can only get a worse-but-not-wrong answer. FIX!
+ /////////////////////////////////////////////////////////////
// for this parameter to be aliased the following must be true
- assert !typeDeref.isImmutable() || typeDeref.isArray();
+ //assert !typeDeref.isImmutable() || typeDeref.isArray();
+
+
primary2secondaryFields.add(
OwnershipAnalysis.getArrayField( typeDeref )
);
fd.getSymbol(), // field
true, // special param initial
betaSoup ); // reachability
- edgePrimaryReflexive.tainedBy(new Integer(i));
addReferenceEdge( primaryI, primaryI, edgePrimaryReflexive );
}
fd.getSymbol(), // field
true, // special param initial
betaSoup ); // reachability
- edgePrimary2Secondary.tainedBy(new Integer(i));
addReferenceEdge( primaryI, hrnAliasBlob, edgePrimary2Secondary );
// ask whether these fields might match any of the other aliased
fd.getSymbol(), // field
true, // special param initial
betaSoupWJ ); // reachability
- edgePrimaryI2PrimaryJ.tainedBy(new Integer(i));
addReferenceEdge( primaryI, primaryJ, edgePrimaryI2PrimaryJ );
}
}
if( as.getType().isClass() ) {
hasFlags = as.getType().getClassDesc().hasFlags();
}
+
+ if(as.getFlag()){
+ hasFlags=as.getFlag();
+ }
hrnSummary = createNewHeapRegionNode(idSummary, // id or null to generate a new one
false, // single object?
public Set<Integer> calculateAliasedParamSet( FlatCall fc,
- boolean isStatic,
FlatMethod fm ) {
+ // to decide if two parameters are aliased, look
+ // at the caller graph (this graph) and if these
+ // two conditions are met, they may be aliased:
+ // 1. The argument labels reference a shared node
+ // 2. The edges to that shared node have a common
+ // reachability state.
+
+ Set<Integer> aliasedIndices = new HashSet<Integer>();
- Hashtable<Integer, LabelNode> paramIndex2ln =
- new Hashtable<Integer, LabelNode>();
- Hashtable<Integer, HashSet<HeapRegionNode> > paramIndex2reachableCallerNodes =
- new Hashtable<Integer, HashSet<HeapRegionNode> >();
+ //System.out.println("Aliases for "+fm+" at "+fc);
+
for( int i = 0; i < fm.numParameters(); ++i ) {
- Integer paramIndex = new Integer( i );
- TempDescriptor tdParam = fm.getParameter( i );
- TypeDescriptor typeParam = tdParam.getType();
+ for( int j = 0; j < i; ++j ) {
- if( typeParam.isImmutable() && !typeParam.isArray() ) {
- // don't bother with this primitive parameter, it
- // cannot affect reachability
- continue;
- }
+ TempDescriptor argTemp_i = fc.getArgMatchingParamIndex( fm, i );
+ LabelNode argLabel_i = getLabelNodeFromTemp( argTemp_i );
- // now depending on whether the callee is static or not
- // we need to account for a "this" argument in order to
- // find the matching argument in the caller context
- TempDescriptor argTemp_i;
- if( isStatic ) {
- argTemp_i = fc.getArg(paramIndex);
- } else {
- if( paramIndex.equals(0) ) {
- argTemp_i = fc.getThis();
- } else {
- argTemp_i = fc.getArg(paramIndex - 1);
- }
- }
+ TempDescriptor argTemp_j = fc.getArgMatchingParamIndex( fm, j );
+ LabelNode argLabel_j = getLabelNodeFromTemp( argTemp_j );
- // in non-static methods there is a "this" pointer
- // that should be taken into account
- if( isStatic ) {
- assert fc.numArgs() == fm.numParameters();
- } else {
- assert fc.numArgs() + 1 == fm.numParameters();
- }
+ /*
+ System.out.println(" "+argTemp_i.getType()+" "+argTemp_i+" and "+
+ argTemp_j.getType()+" "+argTemp_j+" aliased?");
+ */
- LabelNode argLabel_i = getLabelNodeFromTemp(argTemp_i);
- paramIndex2ln.put(paramIndex, argLabel_i);
- }
+ // first condition--do these arguments
+ // reference any common nodes?
+ Iterator<ReferenceEdge> edgeItr;
- Iterator lnArgItr = paramIndex2ln.entrySet().iterator();
- while( lnArgItr.hasNext() ) {
- Map.Entry me = (Map.Entry)lnArgItr.next();
- Integer index = (Integer) me.getKey();
- LabelNode lnArg_i = (LabelNode) me.getValue();
+ Set<HeapRegionNode> hrnSetI = new HashSet<HeapRegionNode>();
+ edgeItr = argLabel_i.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ hrnSetI.add( edgeItr.next().getDst() );
+ }
- HashSet<HeapRegionNode> reachableNodes = new HashSet<HeapRegionNode>();
- HashSet<HeapRegionNode> todoNodes = new HashSet<HeapRegionNode>();
+ Set<HeapRegionNode> hrnSetJ = new HashSet<HeapRegionNode>();
+ edgeItr = argLabel_j.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ hrnSetJ.add( edgeItr.next().getDst() );
+ }
- // to find all reachable nodes, start with label referencees
- Iterator<ReferenceEdge> edgeArgItr = lnArg_i.iteratorToReferencees();
- while( edgeArgItr.hasNext() ) {
- ReferenceEdge edge = edgeArgItr.next();
- todoNodes.add( edge.getDst() );
- }
+ Set<HeapRegionNode> intersection =
+ new HashSet<HeapRegionNode>( hrnSetI );
+ intersection.retainAll( hrnSetJ );
- // then follow links until all reachable nodes have been found
- while( !todoNodes.isEmpty() ) {
- HeapRegionNode hrn = todoNodes.iterator().next();
- todoNodes.remove(hrn);
- reachableNodes.add(hrn);
+ // condition two--for each shared node, do the reference
+ // edges to it from arguments have a common reachability
+ // state that is *ALSO* on the shared node?
+ boolean foundAlias = false;
- Iterator<ReferenceEdge> edgeItr = hrn.iteratorToReferencees();
- while( edgeItr.hasNext() ) {
- ReferenceEdge edge = edgeItr.next();
+ Iterator<HeapRegionNode> hrnItr = intersection.iterator();
+ while( hrnItr.hasNext() ) {
+ HeapRegionNode hrn = hrnItr.next();
- if( !reachableNodes.contains(edge.getDst() ) ) {
- todoNodes.add(edge.getDst() );
- }
- }
- }
+ ReferenceEdge ei = argLabel_i.getReferenceTo( hrn,
+ argTemp_i.getType(),
+ null );
- // save for later
- paramIndex2reachableCallerNodes.put(index, reachableNodes);
- }
+ ReferenceEdge ej = argLabel_j.getReferenceTo( hrn,
+ argTemp_j.getType(),
+ null );
+ assert ei != null;
+ assert ej != null;
- Set<Integer> aliasedIndices = new HashSet<Integer>();
+ ReachabilitySet allStatesForParamI =
+ ei.getBeta().intersection( hrn.getAlpha() );
- // check for arguments that are aliased
- for( int i = 0; i < fm.numParameters(); ++i ) {
- for( int j = 0; j < i; ++j ) {
- HashSet<HeapRegionNode> s1 = paramIndex2reachableCallerNodes.get( i );
- HashSet<HeapRegionNode> s2 = paramIndex2reachableCallerNodes.get( j );
+ ReachabilitySet allStatesForParamJ =
+ ej.getBeta().intersection( hrn.getAlpha() );
- // some parameters are immutable or primitive, so skip em
- if( s1 == null || s2 == null ) {
- continue;
- }
+ ReachabilitySet commonStates =
+ allStatesForParamI.intersection( allStatesForParamJ );
+
+ if( !commonStates.isEmpty() ) {
+ foundAlias = true;
+ aliasedIndices.add( new Integer( i ) );
+ aliasedIndices.add( new Integer( j ) );
- Set<HeapRegionNode> intersection = new HashSet<HeapRegionNode>(s1);
- intersection.retainAll(s2);
+ //System.out.println( " yes!" );
+ }
+ }
- if( !intersection.isEmpty() ) {
- aliasedIndices.add( new Integer( i ) );
- aliasedIndices.add( new Integer( j ) );
+ // as soon as we detect one possible way to alias
+ // these parameters, skip on to another pair
+ if( foundAlias ) {
+ continue;
}
}
}
+ if( !aliasedIndices.isEmpty() ) {
+ try {
+ writeGraph( "foundaliases",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
+ } catch( Exception e ) {}
+ /*
+ System.out.println("FlatCall="+fc+
+ "\nflat method="+fm+
+ "\nAliases="+aliasedIndices );
+ */
+ }
+
return aliasedIndices;
}
ParameterDecomposition pd // if this is not null, we're calling after analysis
) {
-
- // this debug snippet is harmless for regular use and INVALUABLE at debug time
- // to see what potentially goes wrong when a specific method calls another
- String debugCaller = "foo";
- String debugCallee = "bar";
- //String debugCaller = "StandardEngine";
- //String debugCaller = "register_by_type";
- //String debugCaller = "register_by_type_front";
- //String debugCaller = "addFirst";
- //String debugCallee = "LinkedListElement";
-
- if( mc.getDescriptor().getSymbol().equals( debugCaller ) &&
- fm.getMethod().getSymbol().equals( debugCallee ) ) {
+ if( debugCallMap &&
+ mc.getDescriptor().getSymbol().equals( debugCaller ) &&
+ fm.getMethod().getSymbol().equals( debugCallee )
+ ) {
try {
- writeGraph( "debug1BeforeCall", true, true, true, false, false );
- ogCallee.writeGraph( "debug0Callee", true, true, true, false, false );
+ writeGraph("debug1BeforeCall",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
+
+ ogCallee.writeGraph("debug0Callee",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
} catch( IOException e ) {}
System.out.println( " "+mc+" is calling "+fm );
// now depending on whether the callee is static or not
// we need to account for a "this" argument in order to
// find the matching argument in the caller context
- TempDescriptor argTemp_i;
- if( isStatic ) {
- argTemp_i = fc.getArg( paramIndex );
- } else {
- if( paramIndex.equals( 0 ) ) {
- argTemp_i = fc.getThis();
- } else {
- argTemp_i = fc.getArg( paramIndex - 1 );
- }
- }
-
- // in non-static methods there is a "this" pointer
- // that should be taken into account
- if( isStatic ) {
- assert fc.numArgs() == fm.numParameters();
- } else {
- assert fc.numArgs() + 1 == fm.numParameters();
- }
+ TempDescriptor argTemp_i = fc.getArgMatchingParamIndex( fm, paramIndex );
// remember which caller arg label maps to param index
LabelNode argLabel_i = getLabelNodeFromTemp( argTemp_i );
if( (hrn.getNumReferencers() == 1) || // case 1
(hrn.isSingleObject() && argLabel_i.getNumReferencees() == 1) // case 2
) {
-
- effectCalleeStrongUpdates( paramIndex, ogCallee, hrn );
+ if( !DISABLE_STRONG_UPDATES ) {
+ effectCalleeStrongUpdates( paramIndex, ogCallee, hrn );
+ }
}
}
}
Hashtable< Integer, Set<Vector> > edges_up_dr = new Hashtable< Integer, Set<Vector> >();
Hashtable< Integer, Set<Vector> > edges_up_r = new Hashtable< Integer, Set<Vector> >();
-
// so again, with respect to some arg i...
lnArgItr = paramIndex2ln.entrySet().iterator();
while( lnArgItr.hasNext() ) {
// in the caller graph
Set sCallee = ogCallee.id2hrn.entrySet();
Iterator iCallee = sCallee.iterator();
+
while( iCallee.hasNext() ) {
Map.Entry meCallee = (Map.Entry) iCallee.next();
Integer idCallee = (Integer) meCallee.getKey();
// otherwise the caller src and dst pair can match the edge, so make it
ReferenceEdge edgeNewInCaller = edgeNewInCallerTemplate.copy();
edgeNewInCaller.setSrc( src );
- edgeNewInCaller.setDst( dst );
+ edgeNewInCaller.setDst( dst );
+
+ // handle taint info if callee created this edge
+ // added by eom
+ Set<Integer> pParamSet=idPrimary2paramIndexSet.get(dst.getID());
+ Set<Integer> sParamSet=idSecondary2paramIndexSet.get(dst.getID());
+ HashSet<Integer> paramSet=new HashSet<Integer>();
+ if(pParamSet!=null){
+ paramSet.addAll(pParamSet);
+ }
+ if(sParamSet!=null){
+ paramSet.addAll(sParamSet);
+ }
+ Iterator<Integer> paramIter=paramSet.iterator();
+ int newTaintIdentifier=0;
+ while(paramIter.hasNext()){
+ Integer paramIdx=paramIter.next();
+ edgeNewInCaller.tainedBy(paramIdx);
+ }
ReferenceEdge edgeExisting = src.getReferenceTo( dst,
edgeNewInCaller.getType(),
}
+
// return value may need to be assigned in caller
TempDescriptor returnTemp = fc.getReturnTemp();
if( returnTemp != null && !returnTemp.getType().isImmutable() ) {
}
- if( mc.getDescriptor().getSymbol().equals( debugCaller ) &&
- fm.getMethod().getSymbol().equals( debugCallee ) ) {
+ /*
+ if( debugCallMap &&
+ mc.getDescriptor().getSymbol().equals( debugCaller ) &&
+ fm.getMethod().getSymbol().equals( debugCallee )
+ ) {
+
try {
- writeGraph( "debug7JustBeforeMergeToKCapacity", true, true, true, false, false );
+ writeGraph("debug7JustBeforeMergeToKCapacity",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
} catch( IOException e ) {}
}
-
+ */
// merge the shadow nodes of allocation sites back down to normal capacity
}
- if( mc.getDescriptor().getSymbol().equals( debugCaller ) &&
- fm.getMethod().getSymbol().equals( debugCallee ) ) {
+ /*
+ if( debugCallMap &&
+ mc.getDescriptor().getSymbol().equals( debugCaller ) &&
+ fm.getMethod().getSymbol().equals( debugCallee )
+ ) {
+
try {
- writeGraph( "debug8JustBeforeSweep", true, true, true, false, false );
+ writeGraph( "debug8JustBeforeSweep",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
} catch( IOException e ) {}
}
+ */
// improve reachability as much as possible
- globalSweep();
-
+ if( !DISABLE_GLOBAL_SWEEP ) {
+ globalSweep();
+ }
- if( mc.getDescriptor().getSymbol().equals( debugCaller ) &&
- fm.getMethod().getSymbol().equals( debugCallee ) ) {
+ if( debugCallMap &&
+ mc.getDescriptor().getSymbol().equals( debugCaller ) &&
+ fm.getMethod().getSymbol().equals( debugCallee )
+ ) {
+
try {
- writeGraph( "debug9endResolveCall", true, true, true, false, false );
+ writeGraph( "debug9endResolveCall",
+ true, // write labels (variables)
+ true, // selectively hide intermediate temp vars
+ true, // prune unreachable heap regions
+ false, // show back edges to confirm graph validity
+ false, // show parameter indices (unmaintained!)
+ true, // hide subset reachability states
+ true); // hide edge taints
} catch( IOException e ) {}
System.out.println( " "+mc+" done calling "+fm );
++x;
- if( x > 2 ) {
- System.exit( -1 );
+ if( x == debugCallMapCount ) {
+ System.exit( 0 );
}
}
}
edgeToMerge.setBeta(
edgeToMerge.getBeta().union(edgeA.getBeta() )
);
- //TODO eom
edgeToMerge.unionTaintIdentifier(edgeA.getTaintIdentifier());
if( !edgeA.isInitialParam() ) {
edgeToMerge.setIsInitialParam(false);
Set<HeapRegionNode> common = new HashSet<HeapRegionNode>();
if( aliasDetected ) {
common = findCommonReachableNodes( hrn1, hrn2 );
- assert !common.isEmpty();
+ if( !(DISABLE_STRONG_UPDATES || DISABLE_GLOBAL_SWEEP) ) {
+ assert !common.isEmpty();
+ }
}
return common;
}
+ /*
// for writing ownership graphs to dot files
public void writeGraph(MethodContext mc,
FlatNode fn,
);
}
+ public void writeGraph(MethodContext mc,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings,
+ boolean hideSubsetReachability
+ ) throws java.io.IOException {
+
+ writeGraph(mc+"COMPLETE",
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings,
+ hideSubsetReachability
+ );
+ }
+
public void writeGraph(MethodContext mc,
Integer numUpdate,
boolean writeLabels,
boolean writeParamMappings
) throws java.io.IOException {
+ writeGraph(mc+"COMPLETE"+String.format("%05d", numUpdate),
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings
+ );
+ }
+ public void writeGraph(MethodContext mc,
+ Integer numUpdate,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings,
+ boolean hideSubsetReachability
+ ) throws java.io.IOException {
writeGraph(mc+"COMPLETE"+String.format("%05d", numUpdate),
writeLabels,
labelSelect,
pruneGarbage,
writeReferencers,
- writeParamMappings
+ writeParamMappings,
+ hideSubsetReachability
);
}
boolean writeReferencers,
boolean writeParamMappings
) throws java.io.IOException {
+ writeGraph(graphName,
+ writeLabels,
+ labelSelect,
+ pruneGarbage,
+ writeReferencers,
+ writeParamMappings,
+ false
+ );
+ }
+ */
+
+ public void writeGraph(String graphName,
+ boolean writeLabels,
+ boolean labelSelect,
+ boolean pruneGarbage,
+ boolean writeReferencers,
+ boolean writeParamMappings,
+ boolean hideSubsetReachability,
+ boolean hideEdgeTaints
+ ) throws java.io.IOException {
// remove all non-word characters from the graph name so
// the filename and identifier in dot don't cause errors
bw,
null,
visited,
- writeReferencers);
+ writeReferencers,
+ hideSubsetReachability,
+ hideEdgeTaints);
}
}
}
bw,
null,
visited,
- writeReferencers);
+ writeReferencers,
+ hideSubsetReachability,
+ hideEdgeTaints);
}
bw.write(" " + ln.toString() +
" -> " + hrn.toString() +
- "[label=\"" + edge.toGraphEdgeString() +
+ "[label=\"" + edge.toGraphEdgeString(hideSubsetReachability,
+ hideEdgeTaints) +
"\",decorate];\n");
}
}
BufferedWriter bw,
TempDescriptor td,
HashSet<HeapRegionNode> visited,
- boolean writeReferencers
+ boolean writeReferencers,
+ boolean hideSubsetReachability,
+ boolean hideEdgeTaints
) throws java.io.IOException {
if( visited.contains(hrn) ) {
attributes += hrn.getDescription() +
"\\n" +
- hrn.getAlphaString() +
+ hrn.getAlphaString(hideSubsetReachability) +
"\"]";
bw.write(" " + hrn.toString() + attributes + ";\n");
case VISIT_HRN_WRITE_FULL:
bw.write(" " + hrn.toString() +
" -> " + hrnChild.toString() +
- "[label=\"" + edge.toGraphEdgeString() +
+ "[label=\"" + edge.toGraphEdgeString(hideSubsetReachability,
+ hideEdgeTaints) +
"\",decorate];\n");
break;
}
bw,
td,
visited,
- writeReferencers);
+ writeReferencers,
+ hideSubsetReachability,
+ hideEdgeTaints);
}
}
}
+ public void depropagateTaintIdentifier(HeapRegionNode hrn, int newTaintIdentifier, HashSet<HeapRegionNode> visitedSet){
+
+ HashSet<ReferenceEdge> setEdge=hrn.referencers;
+ Iterator<ReferenceEdge> iter=setEdge.iterator();
+ while(iter.hasNext()){
+ ReferenceEdge edge= iter.next();
+ edge.minusTaintIdentifier(newTaintIdentifier);
+ if(edge.getSrc() instanceof HeapRegionNode){
+
+ HeapRegionNode refHRN=(HeapRegionNode)edge.getSrc();
+ //check whether it is reflexive edge
+ if(!refHRN.equals(hrn) && !visitedSet.contains(refHRN)){
+ visitedSet.add(refHRN);
+ depropagateTaintIdentifier((HeapRegionNode)edge.getSrc(),newTaintIdentifier,visitedSet);
+ }
+
+ }
+ }
+
+ }
+
}