parentWriteTable.put(td, parentEffectsSet);
}
+
+ Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongUpdateTable = set
+ .getStrongUpdateTable();
+ Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> parentstrongUpdateTable = parent
+ .getSeseEffectsSet().getStrongUpdateTable();
+ keys = strongUpdateTable.keySet();
+ keyIter = keys.iterator();
+ while (keyIter.hasNext()) {
+ TempDescriptor td = (TempDescriptor) keyIter.next();
+ HashSet<SESEEffectsKey> effectsSet = strongUpdateTable.get(td);
+ HashSet<SESEEffectsKey> parentEffectsSet = parentstrongUpdateTable
+ .get(td);
+ if (parentEffectsSet == null) {
+ parentEffectsSet = new HashSet<SESEEffectsKey>();
+ }
+
+ for (Iterator iterator = effectsSet.iterator(); iterator
+ .hasNext();) {
+ SESEEffectsKey seseKey = (SESEEffectsKey) iterator
+ .next();
+ parentEffectsSet.add(new SESEEffectsKey(seseKey
+ .getFieldDescriptor(), seseKey
+ .getTypeDescriptor(), seseKey.getHRNId()));
+ }
+
+ parentstrongUpdateTable.put(td, parentEffectsSet);
+ }
}
while (edgeIter.hasNext()) {
ReferenceEdge edge = edgeIter.next();
- if(edge.getTaintIdentifier()>0){
+ if(edge.getTaintIdentifier()>0){
HeapRegionNode accessHRN = edge.getDst();
+ /// follow the chain of reference to identify possible accesses
+ Iterator<ReferenceEdge> referIter=accessHRN.iteratorToReferencers();
+ while (referIter.hasNext()) {
+ ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
+
+ if (referEdge.getTaintIdentifier() > 0) {
+ HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
+ followReference(accessHRN, referSet, new HashSet<HeapRegionNode>(),
+ currentSESE);
+
+ Iterator<TempDescriptor> referSetIter=referSet.iterator();
+ while (referSetIter.hasNext()) {
+ TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
+ .next();
+ currentSESE.readEffects(tempDescriptor, field
+ .getSymbol(), src.getType(), accessHRN
+ .getID());
+ }
+ }
+ }
+ ///
affectedTDSet = getReferenceNodeSet(accessHRN);
affectedIter = affectedTDSet.iterator();
while (affectedIter.hasNext()) {
LabelNode dstLN = og.td2ln.get(dst);
if (dstLN != null) {
+ // check possible strong updates
+ boolean strongUpdate = false;
+
+ if( !field.getType().isImmutable() || field.getType().isArray() ) {
+ Iterator<ReferenceEdge> itrXhrn = dstLN.iteratorToReferencees();
+ while( itrXhrn.hasNext() ) {
+ ReferenceEdge edgeX = itrXhrn.next();
+ HeapRegionNode hrnX = edgeX.getDst();
+
+ // we can do a strong update here if one of two cases holds
+ if( field != null &&
+ field != OwnershipAnalysis.getArrayField( field.getType() ) &&
+ ( (hrnX.getNumReferencers() == 1) || // case 1
+ (hrnX.isSingleObject() && dstLN.getNumReferencees() == 1) // case 2
+ )
+ ) {
+ strongUpdate = true;
+ }
+ }
+ }
+
HashSet<TempDescriptor> affectedTDSet = getAccessedTaintNodeSet(dstLN);
Iterator<TempDescriptor> affectedIter = affectedTDSet
if (field.getType().isImmutable()) {
currentSESE.writeEffects(affectedTD, field
.getSymbol(), dst.getType(), hrn
- .getID());
+ .getID(),strongUpdate);
} else {
Iterator<ReferenceEdge> referencers = hrn
currentSESE.writeEffects(affectedTD,
field.getSymbol(), dst
.getType(),
- referenceEdge.getDst().getID());
+ referenceEdge.getDst().getID(),strongUpdate);
}
}
}
ReferenceEdge edge = edgeIter.next();
if (edge.getTaintIdentifier() > 0) {
HeapRegionNode accessHRN = edge.getDst();
+ /// follow the chain of reference to identify possible accesses
+ Iterator<ReferenceEdge> referIter=accessHRN.iteratorToReferencers();
+ while (referIter.hasNext()) {
+ ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
+
+ if (referEdge.getTaintIdentifier() > 0) {
+ HashSet<TempDescriptor> referSet = new HashSet<TempDescriptor>();
+ followReference(accessHRN, referSet, new HashSet<HeapRegionNode>(),
+ currentSESE);
+ Iterator<TempDescriptor> referSetIter=referSet.iterator();
+ while (referSetIter.hasNext()) {
+ TempDescriptor tempDescriptor = (TempDescriptor) referSetIter
+ .next();
+ currentSESE.writeEffects(tempDescriptor, field
+ .getSymbol(), dst.getType(), accessHRN
+ .getID(),strongUpdate);
+ }
+
+ }
+
+ }
+ ///
affectedTDSet = getReferenceNodeSet(accessHRN);
affectedIter = affectedTDSet.iterator();
while (affectedIter.hasNext()) {
HeapRegionNode hrn = hrnIter.next();
currentSESE.writeEffects(affectedTD, field
.getSymbol(), dst.getType(), hrn
- .getID());
+ .getID(),strongUpdate);
}
i + base);
Set<EffectsKey> writeSet = me.getEffects().getWritingSet(
i + base);
+
+ Set<EffectsKey> strongUpdateSet = me.getEffects().getStrongUpdateSet(
+ i + base);
LabelNode argLN = og.td2ln.get(arg);
if (argLN != null) {
currentSESE.writeEffects(affectedTD,
key.getFieldDescriptor(), key
.getTypeDescriptor(),
- hrnID);
+ hrnID,false);
+ }
+
+ }
+ }
+
+ if (strongUpdateSet != null) {
+ Iterator<EffectsKey> strongUpdateIter = strongUpdateSet
+ .iterator();
+ while (strongUpdateIter.hasNext()) {
+ EffectsKey key = strongUpdateIter.next();
+
+ Set<Integer> hrnSet = getCallerHRNId(
+ new Integer(i + base), calleeOG,
+ key.getHRNId(), decomp);
+ Iterator<Integer> hrnIter = hrnSet
+ .iterator();
+ while (hrnIter.hasNext()) {
+ Integer hrnID = (Integer) hrnIter
+ .next();
+ currentSESE.writeEffects(affectedTD,
+ key.getFieldDescriptor(), key
+ .getTypeDescriptor(),
+ hrnID,true);
}
}
}
+
}
}
}
+ private void followReference(HeapRegionNode hrn,HashSet<TempDescriptor> tdSet, HashSet<HeapRegionNode> visited, FlatSESEEnterNode currentSESE){
+
+ Iterator<ReferenceEdge> referIter=hrn.iteratorToReferencers();
+ // check whether hrn is referenced by TD
+ while (referIter.hasNext()) {
+ ReferenceEdge referEdge = (ReferenceEdge) referIter.next();
+ if(referEdge.getSrc() instanceof LabelNode){
+ LabelNode ln=(LabelNode)referEdge.getSrc();
+ if(currentSESE.getInVarSet().contains(ln.getTempDescriptor())){
+ tdSet.add(ln.getTempDescriptor());
+ }
+ }else if(referEdge.getSrc() instanceof HeapRegionNode){
+ HeapRegionNode nextHRN=(HeapRegionNode)referEdge.getSrc();
+ if(!visited.contains(nextHRN)){
+ visited.add(nextHRN);
+ followReference(nextHRN,tdSet,visited,currentSESE);
+ }
+
+ }
+ }
+
+ }
+
private Set<Integer> getCallerHRNId(Integer paramIdx,
OwnershipGraph calleeOG, Integer calleeHRNId,
ParameterDecomposition paramDecom) {
public class SESEEffectsSet {
private Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> readTable;
private Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> writeTable;
+ private Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> strongUpdateTable;
public SESEEffectsSet() {
readTable = new Hashtable<TempDescriptor, HashSet<SESEEffectsKey>>();
writeTable = new Hashtable<TempDescriptor, HashSet<SESEEffectsKey>>();
+ strongUpdateTable = new Hashtable<TempDescriptor, HashSet<SESEEffectsKey>>();
}
public void addReadingVar(TempDescriptor td, SESEEffectsKey access) {
public Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> getWriteTable() {
return writeTable;
}
+
+ public Hashtable<TempDescriptor, HashSet<SESEEffectsKey>> getStrongUpdateTable() {
+ return strongUpdateTable;
+ }
public void addWritingVar(TempDescriptor td, SESEEffectsKey access) {
HashSet<SESEEffectsKey> aSet = writeTable.get(td);
aSet.add(access);
writeTable.put(td, aSet);
}
+
+ public void addStrongUpdateVar(TempDescriptor td, SESEEffectsKey access) {
+ HashSet<SESEEffectsKey> aSet = strongUpdateTable.get(td);
+ if (aSet == null) {
+ aSet = new HashSet<SESEEffectsKey>();
+ }
+ aSet.add(access);
+ strongUpdateTable.put(td, aSet);
+ }
public Set<SESEEffectsKey> getReadingSet(TempDescriptor td) {
return readTable.get(td);
writer.write("Live-in Var " + td + " Write=" + keyStr+"\n");
}
+ keySet = strongUpdateTable.keySet();
+ iter = keySet.iterator();
+ while (iter.hasNext()) {
+ TempDescriptor td = iter.next();
+ Set<SESEEffectsKey> effectSet = strongUpdateTable.get(td);
+ String keyStr = "{";
+ if (effectSet != null) {
+ Iterator<SESEEffectsKey> effectIter = effectSet.iterator();
+ while (effectIter.hasNext()) {
+ SESEEffectsKey key = effectIter.next();
+ keyStr += " " + key;
+ }
+ }
+ keyStr+=" }";
+ writer.write("Live-in Var " + td + " StrongUpdate=" + keyStr+"\n");
+ }
+
return writer.toString();
}
SESEEffectsSet in = (SESEEffectsSet) o;
if (getReadTable().equals(in.getReadTable())
- && getWriteTable().equals(in.getWriteTable())) {
+ && getWriteTable().equals(in.getWriteTable())
+ && getStrongUpdateTable().equals(in.getStrongUpdateTable())) {
return true;
} else {
return false;
public int hashCode() {
int hash = 1;
- hash += getReadTable().hashCode() + getWriteTable().hashCode() * 31;
+ hash += getReadTable().hashCode() + getWriteTable().hashCode() * 31 +getStrongUpdateTable().hashCode();
return hash;
}
private Hashtable<Integer, HashSet<EffectsKey>> readTable;
private Hashtable<Integer, HashSet<EffectsKey>> writeTable;
+ private Hashtable<Integer, HashSet<EffectsKey>> strongUpdateTable;
public EffectsSet() {
readTable = new Hashtable<Integer, HashSet<EffectsKey>>();
writeTable = new Hashtable<Integer, HashSet<EffectsKey>>();
+ strongUpdateTable = new Hashtable<Integer, HashSet<EffectsKey>>();
}
public void addReadingVar(Integer idx, EffectsKey access) {
}
}
+
+ public void addStrongUpdateEffectsSet(Integer idx, HashSet<EffectsKey> newSet) {
+
+ if (newSet != null) {
+ HashSet<EffectsKey> aSet = strongUpdateTable.get(idx);
+ if (aSet == null) {
+ aSet = new HashSet<EffectsKey>();
+ }
+ aSet.addAll(newSet);
+ strongUpdateTable.put(idx, aSet);
+ }
+
+ }
+
public Hashtable<Integer, HashSet<EffectsKey>> getReadTable() {
return readTable;
public Hashtable<Integer, HashSet<EffectsKey>> getWriteTable() {
return writeTable;
}
+
+ public Hashtable<Integer, HashSet<EffectsKey>> getStrongUpdateTable() {
+ return strongUpdateTable;
+ }
public void addWritingVar(Integer idx, EffectsKey access) {
HashSet<EffectsKey> aSet = writeTable.get(idx);
aSet = new HashSet<EffectsKey>();
}
aSet.add(access);
- writeTable.put(idx, aSet);
+ writeTable.put(idx, aSet);
+ }
+
+ public void addStrongUpdateVar(Integer idx, EffectsKey access) {
+ HashSet<EffectsKey> aSet = strongUpdateTable.get(idx);
+ if (aSet == null) {
+ aSet = new HashSet<EffectsKey>();
+ }
+ aSet.add(access);
+ strongUpdateTable.put(idx, aSet);
}
public Set<EffectsKey> getReadingSet(Integer idx) {
public Set<EffectsKey> getWritingSet(Integer idx) {
return writeTable.get(idx);
}
+
+ public Set<EffectsKey> getStrongUpdateSet(Integer idx) {
+ return strongUpdateTable.get(idx);
+ }
public void printSet() {
System.out.println("writeTable=>" + writeTable.hashCode());
EffectsSet in = (EffectsSet) o;
if (getReadTable().equals(in.getReadTable())
- && getWriteTable().equals(in.getWriteTable())) {
+ && getWriteTable().equals(in.getWriteTable())
+ && getStrongUpdateTable().equals(in.getStrongUpdateTable())) {
return true;
} else {
return false;
public int hashCode() {
int hash = 1;
- hash += getReadTable().hashCode() + getWriteTable().hashCode() * 31;
+ hash += getReadTable().hashCode() + getWriteTable().hashCode() * 31 + getStrongUpdateTable().hashCode();
return hash;
}
LabelNode ln = getLabelNodeFromTemp(og, dstDesc);
if (ln != null) {
+ /// check possible strong updates
+ boolean strongUpdate = false;
+ if( !fieldDesc.getType().isImmutable() || fieldDesc.getType().isArray() ) {
+ Iterator<ReferenceEdge> itrXhrn = ln.iteratorToReferencees();
+ while( itrXhrn.hasNext() ) {
+ ReferenceEdge edgeX = itrXhrn.next();
+ HeapRegionNode hrnX = edgeX.getDst();
+
+ if( fieldDesc != null &&
+ fieldDesc != OwnershipAnalysis.getArrayField( fieldDesc.getType() ) &&
+ ( (hrnX.getNumReferencers() == 1) || // case 1
+ (hrnX.isSingleObject() && ln.getNumReferencees() == 1) // case 2
+ )
+ ) {
+ strongUpdate = true;
+ }
+ }
+ }
+ ////
+
Iterator<ReferenceEdge> heapRegionsItr = ln.iteratorToReferencees();
while (heapRegionsItr.hasNext()) {
Integer paramID = paramIter.next();
effectsSet.addWritingVar(paramID, new EffectsKey(
fieldDesc.getSymbol(), dstDesc.getType(),hrn.getID()));
+ if(strongUpdate){
+ effectsSet.addStrongUpdateVar(paramID, new EffectsKey(
+ fieldDesc.getSymbol(), dstDesc.getType(),hrn.getID()));
+ }
}
}
Integer paramID = paramIter.next();
effectsSet.addWritingVar(paramID, new EffectsKey(
fieldDesc.getSymbol(), dstDesc.getType(),hrn.getID()));
+ if(strongUpdate){
+ effectsSet.addStrongUpdateVar(paramID, new EffectsKey(
+ fieldDesc.getSymbol(), dstDesc.getType(),hrn.getID()));
+ }
}
}
.getWriteTable().get(calleeParamIdx);
effectsSet.addWritingEffectsSet(paramIdx, newSet);
}
+
+ // handle strong update effects
+ paramIter = paramIDs.iterator();
+ while (paramIter.hasNext()) {
+ Integer paramIdx = paramIter.next();
+ HashSet<EffectsKey> newSet = callee.getEffects()
+ .getStrongUpdateTable().get(calleeParamIdx);
+ effectsSet.addStrongUpdateEffectsSet(paramIdx, newSet);
+ }
}
return 31*id;
}
- public void writeEffects(TempDescriptor td, String fd, TypeDescriptor type, Integer hrnId){
+ public void writeEffects(TempDescriptor td, String fd, TypeDescriptor type, Integer hrnId, boolean strongUpdate){
seseEffectsSet.addWritingVar(td, new SESEEffectsKey(fd, type, hrnId));
+ if(strongUpdate){
+ seseEffectsSet.addStrongUpdateVar(td, new SESEEffectsKey(fd, type, hrnId));
+ }
}
public void readEffects(TempDescriptor td, String fd, TypeDescriptor type, Integer hrnId ){