From: yeom Date: Sat, 3 Oct 2009 06:26:09 +0000 (+0000) Subject: add analyzing SESE effects. generate read&write set for each live-in variable. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=038aee047c4f87bda6d43c9209e3e80ae6e3cfa0;p=IRC.git add analyzing SESE effects. generate read&write set for each live-in variable. --- diff --git a/Robust/src/Analysis/MLP/MLPAnalysis.java b/Robust/src/Analysis/MLP/MLPAnalysis.java index 1c9e8eec..37ae074c 100644 --- a/Robust/src/Analysis/MLP/MLPAnalysis.java +++ b/Robust/src/Analysis/MLP/MLPAnalysis.java @@ -100,7 +100,7 @@ public class MLPAnalysis { notAvailableResults = new Hashtable< FlatNode, Set >(); codePlans = new Hashtable< FlatNode, CodePlan >(); wdvNodesToSpliceIn = new Hashtable< FlatEdge, FlatWriteDynamicVarNode >(); - + FlatMethod fmMain = state.getMethodFlat( typeUtil.getMain() ); @@ -183,6 +183,15 @@ public class MLPAnalysis { // point, in a forward fixed-point pass notAvailableForward( fm ); } + + // new pass + methItr = ownAnalysis.descriptorsToAnalyze.iterator(); + while( methItr.hasNext() ) { + Descriptor d = methItr.next(); + FlatMethod fm = state.getMethodFlat( d ); + methodEffects(fm); + // notAvailableForward( fm ); + } // 7th pass @@ -780,6 +789,419 @@ public class MLPAnalysis { } // end switch } + + private void methodEffects(FlatMethod fm) { + + MethodDescriptor md=fm.getMethod(); + HashSet mcSet=ownAnalysis.getAllMethodContextSetByDescriptor(md); + Iterator mcIter=mcSet.iterator(); + + while(mcIter.hasNext()){ + MethodContext mc=mcIter.next(); + +// System.out.println("#method effects="+fm+" with mc="+mc); + Set visited = new HashSet(); + + Set flatNodesToVisit = new HashSet(); + flatNodesToVisit.add(fm); + + while (!flatNodesToVisit.isEmpty()) { + FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next(); + flatNodesToVisit.remove(fn); + + Stack seseStack = seseStacks.get(fn); + assert seseStack != null; + + if (!seseStack.empty()) { + effects_nodeActions(mc, fn, seseStack.peek()); + } + + flatNodesToVisit.remove(fn); + visited.add(fn); + + for (int i = 0; i < fn.numNext(); i++) { + FlatNode nn = fn.getNext(i); + if (!visited.contains(nn)) { + flatNodesToVisit.add(nn); + } + } + + } + + + } + + } + + private void effects_nodeActions(MethodContext mc, FlatNode fn, + FlatSESEEnterNode currentSESE) { + + OwnershipGraph og = ownAnalysis.getOwnvershipGraphByMethodContext(mc); + + switch (fn.kind()) { + + case FKind.FlatSESEEnterNode: { + + FlatSESEEnterNode fsen = (FlatSESEEnterNode) fn; + assert fsen.equals(currentSESE); + + // uniquely taint each live-in variable + Set set = fsen.getInVarSet(); + Iterator iter = set.iterator(); + int idx = 0; + while (iter.hasNext()) { + TempDescriptor td = iter.next(); + LabelNode ln = og.td2ln.get(td); + if (ln != null) { + int taint = (int) Math.pow(2, idx); + taintLabelNode(ln, taint); + } + idx++; + } + + } + break; + + case FKind.FlatSESEExitNode: { + FlatSESEExitNode fsexit = (FlatSESEExitNode) fn; + + fsexit.getFlatEnter().getSeseEffectsSet().printSet(); + + } + break; + + case FKind.FlatFieldNode: { + + FlatFieldNode ffn = (FlatFieldNode) fn; + TempDescriptor src = ffn.getSrc(); + FieldDescriptor field = ffn.getField(); + + LabelNode srcLN = og.td2ln.get(src); + if (srcLN != null) { + HashSet affectedTDSet = getAccessedTaintNodeSet(srcLN); + Iterator affectedIter = affectedTDSet + .iterator(); + while (affectedIter.hasNext()) { + TempDescriptor affectedTD = affectedIter.next(); + if (currentSESE.getInVarSet().contains(affectedTD)) { + + HashSet hrnSet = getReferenceHeapIDSet(og, + affectedTD); + Iterator hrnIter = hrnSet.iterator(); + while (hrnIter.hasNext()) { + Integer hrnId = hrnIter.next(); + currentSESE.readEffects(affectedTD, field + .getSymbol(), src.getType(), hrnId); + } + } + } + + // / handle tainted case + Iterator edgeIter = srcLN + .iteratorToReferencees(); + while (edgeIter.hasNext()) { + ReferenceEdge edge = edgeIter.next(); + HeapRegionNode dstHRN = edge.getDst(); + + Iterator referenceeIter = dstHRN + .iteratorToReferencees(); + while (referenceeIter.hasNext()) { + ReferenceEdge re = referenceeIter.next(); + + if ((re.getField() == null && ffn.getField() == null) + || (re.getField() != null + && ffn.getField() != null + && re.getField().equals( + ffn.getField().getSymbol()) && re + .getType().equals( + ffn.getField().getType()))) { + int taintIdentifier = re.getTaintIdentifier(); + + if (taintIdentifier > 0) { + HeapRegionNode accessHRN = re.getDst(); + affectedTDSet = getReferenceNodeSet(accessHRN); + + affectedIter = affectedTDSet.iterator(); + while (affectedIter.hasNext()) { + TempDescriptor affectedTD = affectedIter + .next(); + if (currentSESE.getInVarSet().contains( + affectedTD)) { + + HashSet hrnSet = getReferenceHeapIDSet( + og, affectedTD); + Iterator hrnIter = hrnSet + .iterator(); + while (hrnIter.hasNext()) { + Integer hrnId = hrnIter.next(); + currentSESE.readEffects(affectedTD, + field.getSymbol(), src + .getType(), hrnId); + + } + } + } + + } + + } + } + + } + + } + + } + break; + + case FKind.FlatSetFieldNode: { + + FlatSetFieldNode fsen = (FlatSetFieldNode) fn; + TempDescriptor dst = fsen.getDst(); + FieldDescriptor field = fsen.getField(); + + LabelNode dstLN = og.td2ln.get(dst); + if (dstLN != null) { + HashSet affectedTDSet = getAccessedTaintNodeSet(dstLN); + + Iterator affectedIter = affectedTDSet + .iterator(); + + while (affectedIter.hasNext()) { + TempDescriptor affectedTD = affectedIter.next(); + if (currentSESE.getInVarSet().contains(affectedTD)) { + + HashSet hrnSet = getReferenceHeapIDSet(og, + affectedTD); + Iterator hrnIter = hrnSet.iterator(); + while (hrnIter.hasNext()) { + Integer hrnId = hrnIter.next(); + currentSESE.writeEffects(affectedTD, field + .getSymbol(), dst.getType(), hrnId); + } + } + } + + // / handle tainted case + Iterator edgeIter = dstLN + .iteratorToReferencees(); + while (edgeIter.hasNext()) { + ReferenceEdge edge = edgeIter.next(); + HeapRegionNode dstHRN = edge.getDst(); + + Iterator referenceeIter = dstHRN + .iteratorToReferencees(); + while (referenceeIter.hasNext()) { + ReferenceEdge re = referenceeIter.next(); + + if ((re.getField() == null && fsen.getField() == null) + || (re.getField() != null + && fsen.getField() != null + && re.getField().equals( + fsen.getField().getSymbol()) && re + .getType().equals( + fsen.getField().getType()))) { + int taintIdentifier = re.getTaintIdentifier(); + + if (taintIdentifier > 0) { + HeapRegionNode accessHRN = re.getDst(); + affectedTDSet = getReferenceNodeSet(accessHRN); + + affectedIter = affectedTDSet.iterator(); + while (affectedIter.hasNext()) { + TempDescriptor affectedTD = affectedIter + .next(); + if (currentSESE.getInVarSet().contains( + affectedTD)) { + + HashSet hrnSet = getReferenceHeapIDSet( + og, affectedTD); + Iterator hrnIter = hrnSet + .iterator(); + while (hrnIter.hasNext()) { + Integer hrnId = hrnIter.next(); + currentSESE.readEffects(affectedTD, + field.getSymbol(), dst + .getType(), hrnId); + + } + } + } + + } + + } + } + + } + + } + + } + break; + + case FKind.FlatCall: { + FlatCall fc = (FlatCall) fn; + + MethodContext calleeMC = ownAnalysis.getCalleeMethodContext(mc, fc); + + MethodEffects me = ownAnalysis.getMethodEffectsAnalysis() + .getMethodEffectsByMethodContext(calleeMC); + + int base; + if (((MethodDescriptor) calleeMC.getDescriptor()).isStatic()) { + base = 0; + } else { + base = 1; + } + + for (int i = 0; i < fc.numArgs(); i++) { + + TempDescriptor arg = fc.getArg(i); + Set readSet = me.getEffects().getReadingSet( + i + base); + Set writeSet = me.getEffects().getWritingSet( + i + base); + + LabelNode argLN = og.td2ln.get(arg); + if (argLN != null) { + HashSet affectedTDSet = getAccessedTaintNodeSet(argLN); + Iterator affectedIter = affectedTDSet + .iterator(); + + while (affectedIter.hasNext()) { + + TempDescriptor affectedTD = affectedIter.next(); + if (currentSESE.getInVarSet().contains(affectedTD)) { + + if (readSet != null) { + Iterator readIter = readSet + .iterator(); + while (readIter.hasNext()) { + EffectsKey key = readIter.next(); + // TODO need to verify the correctness of + // hrnID + currentSESE.readEffects(affectedTD, key + .getFieldDescriptor(), key + .getTypeDescriptor(), key + .getHRNId()); + } + } + + if (writeSet != null) { + Iterator writeIter = writeSet + .iterator(); + while (writeIter.hasNext()) { + EffectsKey key = writeIter.next(); + currentSESE.writeEffects(affectedTD, key + .getFieldDescriptor(), key + .getTypeDescriptor(), key + .getHRNId()); + } + } + + } + + } + + } + + } + + } + break; + + } + } + + private void taintLabelNode(LabelNode ln, int identifier) { + + Iterator edgeIter = ln.iteratorToReferencees(); + while (edgeIter.hasNext()) { + ReferenceEdge edge = edgeIter.next(); + HeapRegionNode hrn = edge.getDst(); + + Iterator edgeReferencerIter = hrn + .iteratorToReferencers(); + while (edgeReferencerIter.hasNext()) { + ReferenceEdge referencerEdge = edgeReferencerIter.next(); + OwnershipNode node = referencerEdge.getSrc(); + if (node instanceof LabelNode) { + referencerEdge.unionSESETaintIdentifier(identifier); + } + } + + } + + } + + private HashSet getReferenceNodeSet(HeapRegionNode hrn){ + + HashSet returnSet=new HashSet(); + + Iterator edgeIter=hrn.iteratorToReferencers(); + while(edgeIter.hasNext()){ + ReferenceEdge edge=edgeIter.next(); + if(edge.getSrc() instanceof LabelNode){ + LabelNode ln=(LabelNode)edge.getSrc(); + returnSet.add(ln.getTempDescriptor()); + } + } + + return returnSet; + + } + + + private HashSet getReferenceHeapIDSet(OwnershipGraph og, TempDescriptor td){ + + HashSet returnSet=new HashSet(); + + LabelNode ln=og.td2ln.get(td); + Iterator edgeIter=ln.iteratorToReferencees(); + while(edgeIter.hasNext()){ + ReferenceEdge edge=edgeIter.next(); + HeapRegionNode hrn=edge.getDst(); + returnSet.add(hrn.getID()); + } + return returnSet; + } + + + private HashSet getAccessedTaintNodeSet(LabelNode ln){ + + HashSet returnSet=new HashSet(); + + Iterator edgeIter=ln.iteratorToReferencees(); + while(edgeIter.hasNext()){ + ReferenceEdge edge=edgeIter.next(); + HeapRegionNode hrn=edge.getDst(); + + Iterator edgeReferencerIter= hrn.iteratorToReferencers(); + while(edgeReferencerIter.hasNext()){ + ReferenceEdge referencerEdge=edgeReferencerIter.next(); + + + if(referencerEdge.getSrc() instanceof LabelNode){ + if( !((LabelNode)referencerEdge.getSrc()).equals(ln) ){ + + if(referencerEdge.getSESETaintIdentifier() > 0){ + TempDescriptor td=((LabelNode)referencerEdge.getSrc()).getTempDescriptor(); + returnSet.add(td); + } + +// int taintId=referencerEdge.getSESETaintIdentifier(); +// edge.unionSESETaintIdentifier(taintId); + } + } + } + + } + + return returnSet; + + + } private void codePlansForward( FlatMethod fm ) { @@ -1105,9 +1527,34 @@ public class MLPAnalysis { bw.write( "\n\nVariable Results-Out\n----------------\n" +fm.printMethod( variableResults ) ); bw.write( "\n\nNot Available Results-Out\n---------------------\n"+fm.printMethod( notAvailableResults ) ); bw.write( "\n\nCode Plans\n----------\n" +fm.printMethod( codePlans ) ); + bw.write("\n\nSESE Effects\n----------------------\n"+printSESEEffects()); bw.close(); } } + + private String printSESEEffects(){ + + StringWriter writer=new StringWriter(); + + Set keySet=livenessRootView.keySet(); + Iterator keyIter=keySet.iterator(); + + while(keyIter.hasNext()){ + FlatNode fn=keyIter.next(); + if(fn instanceof FlatSESEEnterNode){ + FlatSESEEnterNode seseEnter=(FlatSESEEnterNode)fn; + String result=seseEnter.getSeseEffectsSet().printSet(); + if(result.length()>0){ + writer.write("\nSESE "+seseEnter+"\n"); + writer.write(result); + } + + } + } + + return writer.toString(); + + } private void printSESEHierarchy( BufferedWriter bw ) throws java.io.IOException { bw.write( "SESE Hierarchy\n--------------\n" ); diff --git a/Robust/src/Analysis/MLP/SESEEffectsKey.java b/Robust/src/Analysis/MLP/SESEEffectsKey.java new file mode 100644 index 00000000..fbb58a24 --- /dev/null +++ b/Robust/src/Analysis/MLP/SESEEffectsKey.java @@ -0,0 +1,75 @@ +package Analysis.MLP; + +import IR.TypeDescriptor; + +public class SESEEffectsKey { + + private String fd; + private TypeDescriptor td; + private Integer hrnId; + + public SESEEffectsKey(String fd, TypeDescriptor td, Integer hrnId) { + this.fd = fd; + this.td = td; + this.hrnId = hrnId; + } + + public String getFieldDescriptor() { + return fd; + } + + public TypeDescriptor getTypeDescriptor() { + return td; + } + + public Integer getHRNId() { + return hrnId; + } + + public String toString() { + return "(" + td + ")" + fd + "#" + hrnId; + } + + public int hashCode() { + + int hash = 1; + + if (fd != null) { + hash = hash * 31 + fd.hashCode(); + } + + if (td != null) { + hash += td.getSymbol().hashCode(); + } + + if (hrnId != null) { + hash += hrnId.hashCode(); + } + + return hash; + + } + + public boolean equals(Object o) { + + if (o == null) { + return false; + } + + if (!(o instanceof SESEEffectsKey)) { + return false; + } + + SESEEffectsKey in = (SESEEffectsKey) o; + + if (fd.equals(in.getFieldDescriptor()) + && td.getSymbol().equals(in.getTypeDescriptor().getSymbol()) + && hrnId.equals(in.getHRNId())) { + return true; + } else { + return false; + } + + } + +} diff --git a/Robust/src/Analysis/MLP/SESEEffectsSet.java b/Robust/src/Analysis/MLP/SESEEffectsSet.java new file mode 100644 index 00000000..395bcefd --- /dev/null +++ b/Robust/src/Analysis/MLP/SESEEffectsSet.java @@ -0,0 +1,152 @@ +package Analysis.MLP; + +import java.io.StringWriter; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; + +import IR.Flat.TempDescriptor; + +public class SESEEffectsSet { + private Hashtable> readTable; + private Hashtable> writeTable; + + public SESEEffectsSet() { + readTable = new Hashtable>(); + writeTable = new Hashtable>(); + } + + public void addReadingVar(TempDescriptor td, SESEEffectsKey access) { + HashSet aSet = readTable.get(td); + if (aSet == null) { + aSet = new HashSet(); + } + + aSet.add(access); + readTable.put(td, aSet); + } + + public void addReadingEffectsSet(TempDescriptor td, + HashSet newSet) { + + if (newSet != null) { + HashSet aSet = readTable.get(td); + if (aSet == null) { + aSet = new HashSet(); + } + aSet.addAll(newSet); + readTable.put(td, aSet); + } + + } + + public void addWritingEffectsSet(TempDescriptor td, + HashSet newSet) { + + if (newSet != null) { + HashSet aSet = writeTable.get(td); + if (aSet == null) { + aSet = new HashSet(); + } + aSet.addAll(newSet); + writeTable.put(td, aSet); + } + + } + + public Hashtable> getReadTable() { + return readTable; + } + + public Hashtable> getWriteTable() { + return writeTable; + } + + public void addWritingVar(TempDescriptor td, SESEEffectsKey access) { + HashSet aSet = writeTable.get(td); + if (aSet == null) { + aSet = new HashSet(); + } + aSet.add(access); + writeTable.put(td, aSet); + } + + public Set getReadingSet(TempDescriptor td) { + return readTable.get(td); + } + + public Set getWritingSet(TempDescriptor td) { + return writeTable.get(td); + } + + public String printSet() { + + StringWriter writer=new StringWriter(); + + Set keySet = readTable.keySet(); + Iterator iter = keySet.iterator(); + while (iter.hasNext()) { + TempDescriptor td = iter.next(); + Set effectSet = readTable.get(td); + String keyStr = "{"; + if (effectSet != null) { + Iterator effectIter = effectSet.iterator(); + while (effectIter.hasNext()) { + SESEEffectsKey key = effectIter.next(); + keyStr += " " + key; + } + } + keyStr+=" }"; + writer.write("Live-in Var " + td + " Read=" + keyStr+"\n"); + } + + keySet = writeTable.keySet(); + iter = keySet.iterator(); + while (iter.hasNext()) { + TempDescriptor td = iter.next(); + Set effectSet = writeTable.get(td); + String keyStr = "{"; + if (effectSet != null) { + Iterator effectIter = effectSet.iterator(); + while (effectIter.hasNext()) { + SESEEffectsKey key = effectIter.next(); + keyStr += " " + key; + } + } + keyStr+=" }"; + writer.write("Live-in Var " + td + " Write=" + keyStr+"\n"); + } + + return writer.toString(); + + } + + public boolean equals(Object o) { + if (o == null) { + return false; + } + + if (!(o instanceof SESEEffectsSet)) { + return false; + } + + SESEEffectsSet in = (SESEEffectsSet) o; + + if (getReadTable().equals(in.getReadTable()) + && getWriteTable().equals(in.getWriteTable())) { + return true; + } else { + return false; + } + + } + + public int hashCode() { + int hash = 1; + + hash += getReadTable().hashCode() + getWriteTable().hashCode() * 31; + + return hash; + } +} diff --git a/Robust/src/Analysis/OwnershipAnalysis/MethodEffectsAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/MethodEffectsAnalysis.java index b8c04a33..51c77aa3 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/MethodEffectsAnalysis.java +++ b/Robust/src/Analysis/OwnershipAnalysis/MethodEffectsAnalysis.java @@ -21,6 +21,10 @@ public class MethodEffectsAnalysis { this.methodeffects = methodeffects; mapMethodContextToMethodEffects = new Hashtable(); } + + public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){ + return mapMethodContextToMethodEffects.get(mc); + } public void createNewMapping(MethodContext mcNew) { if(!methodeffects) return; diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java index 19e5f5f8..147cc3c1 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java @@ -297,7 +297,7 @@ public class OwnershipAnalysis { // TaskDescriptor and MethodDescriptor are combined // together, with a common parent class Descriptor private Hashtable mapMethodContextToInitialParamAllocGraph; - public Hashtable mapMethodContextToCompleteOwnershipGraph; + private Hashtable mapMethodContextToCompleteOwnershipGraph; private Hashtable mapFlatNewToAllocationSite; private Hashtable > mapDescriptorToAllocationSiteSet; private Hashtable mapMethodContextToNumUpdates; @@ -340,6 +340,9 @@ public class OwnershipAnalysis { //map each FlatNode to its own internal ownership graph private MethodEffectsAnalysis meAnalysis; + + //keep internal ownership graph by method context and flat node + private Hashtable> mapMethodContextToFlatNodeOwnershipGraph; @@ -415,6 +418,8 @@ public class OwnershipAnalysis { mapHrnIdToAllocationSite = new Hashtable(); + mapMethodContextToFlatNodeOwnershipGraph=new Hashtable>(); + meAnalysis=new MethodEffectsAnalysis(methodEffects); @@ -978,6 +983,13 @@ public class OwnershipAnalysis { break; } + Hashtable table=mapMethodContextToFlatNodeOwnershipGraph.get(mc); + if(table==null){ + table=new Hashtable(); + } + table.put(fn, og); + mapMethodContextToFlatNodeOwnershipGraph.put(mc, table); + return og; } @@ -1377,4 +1389,41 @@ public class OwnershipAnalysis { System.exit(0); } } + + public MethodEffectsAnalysis getMethodEffectsAnalysis(){ + return meAnalysis; + } + + public OwnershipGraph getOwnvershipGraphByMethodContext(MethodContext mc){ + return mapMethodContextToCompleteOwnershipGraph.get(mc); + } + + public HashSet getAllMethodContextSetByDescriptor(Descriptor d){ + return mapDescriptorToAllMethodContexts.get(d); + } + + public MethodContext getCalleeMethodContext(MethodContext callerMC, FlatCall fc){ + + Hashtable table=mapMethodContextToFlatNodeOwnershipGraph.get(callerMC); + + // merge previous ownership graph to calculate corresponding method context + OwnershipGraph mergeOG = new OwnershipGraph( allocationDepth, typeUtil ); + + for(int i=0;i aliasedParamIndices = mergeOG.calculateAliasedParamSet(fc, md.isStatic(), flatm); + MethodContext calleeMC = new MethodContext( md, aliasedParamIndices ); + + return calleeMC; + } + + } diff --git a/Robust/src/Analysis/OwnershipAnalysis/ReferenceEdge.java b/Robust/src/Analysis/OwnershipAnalysis/ReferenceEdge.java index 28d5d492..2fcc443d 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/ReferenceEdge.java +++ b/Robust/src/Analysis/OwnershipAnalysis/ReferenceEdge.java @@ -18,6 +18,7 @@ public class ReferenceEdge { protected OwnershipNode src; protected HeapRegionNode dst; private int taintIdentifier; + private int SESEtaintIdentifier; public ReferenceEdge(OwnershipNode src, @@ -33,6 +34,7 @@ public class ReferenceEdge { this.field = field; this.isInitialParam = isInitialParam; this.taintIdentifier = 0; + this.SESEtaintIdentifier = 0; if( beta != null ) { this.beta = beta; @@ -208,27 +210,29 @@ public class ReferenceEdge { } - public String toGraphEdgeString( boolean hideSubsetReachability ) { - String edgeLabel = ""; + public String toGraphEdgeString(boolean hideSubsetReachability) { + String edgeLabel = ""; - if( type != null ) { - edgeLabel += type.toPrettyString()+"\\n"; - } + if (type != null) { + edgeLabel += type.toPrettyString() + "\\n"; + } - if( field != null ) { - edgeLabel += field+"\\n"; - } + if (field != null) { + edgeLabel += field + "\\n"; + } - if( isInitialParam ) { - edgeLabel += "*init*\\n"; - } - - edgeLabel+="*taint*="+Integer.toBinaryString(taintIdentifier)+"\\n"; + if (isInitialParam) { + edgeLabel += "*init*\\n"; + } - edgeLabel += beta.toStringEscapeNewline(hideSubsetReachability); + edgeLabel += "*taint*=" + Integer.toBinaryString(taintIdentifier) + + "\\n*SESE*=" + Integer.toBinaryString(SESEtaintIdentifier) + + "\\n"; - return edgeLabel; - } + edgeLabel += beta.toStringEscapeNewline(hideSubsetReachability); + + return edgeLabel; + } public String toString() { if( type != null ) { @@ -259,4 +263,17 @@ public class ReferenceEdge { return taintIdentifier; } + public int getSESETaintIdentifier(){ + return SESEtaintIdentifier; + } + + public void setSESETaintIdentifier(int newTaint){ + SESEtaintIdentifier=newTaint; + } + + public void unionSESETaintIdentifier(int newTaint){ + SESEtaintIdentifier=SESEtaintIdentifier | newTaint; + } + + }