}
- public boolean createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
int paramIndex1,
int paramIndex2) {
return og.hasPotentialAlias(paramIndex1, paramIndex2);
}
- public boolean createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
int paramIndex,
AllocationSite alloc) {
return og.hasPotentialAlias(paramIndex, alloc);
}
- public boolean createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
AllocationSite alloc,
int paramIndex) {
return og.hasPotentialAlias(paramIndex, alloc);
}
- public boolean createsPotentialAliases(Descriptor taskOrMethod,
+ public Set<HeapRegionNode> createsPotentialAliases(Descriptor taskOrMethod,
AllocationSite alloc1,
AllocationSite alloc2) {
}
+ public String prettyPrintNodeSet( Set<HeapRegionNode> s ) {
+ String out = "{\n";
+
+ Iterator<HeapRegionNode> i = s.iterator();
+ while( i.hasNext() ) {
+ HeapRegionNode n = i.next();
+
+ AllocationSite as = n.getAllocationSite();
+ if( as == null ) {
+ out += " "+n.toString()+",\n";
+ } else {
+ out += " "+n.toString()+"-"+as.toStringVerbose()+",\n";
+ }
+ }
+
+ out += "}";
+ return out;
+ }
+
+
// use the methods given above to check every possible alias
// between task parameters and flagged allocation sites reachable
// from the task
HashSet<AllocationSite> allocSites = getFlaggedAllocationSitesReachableFromTask(td);
+ Set<HeapRegionNode> common;
+
// for each task parameter, check for aliases with
// other task parameters and every allocation site
// reachable from this task
// for the ith parameter check for aliases to all
// higher numbered parameters
for( int j = i + 1; j < fm.numParameters(); ++j ) {
- if( createsPotentialAliases(td, i, j) ) {
+ common = createsPotentialAliases(td, i, j);
+ if( !common.isEmpty() ) {
foundSomeAlias = true;
bw.write("Potential alias between parameters "+i+" and "+j+".\n");
+ bw.write(prettyPrintNodeSet( common )+"\n" );
}
}
Iterator allocItr = allocSites.iterator();
while( allocItr.hasNext() ) {
AllocationSite as = (AllocationSite) allocItr.next();
- if( createsPotentialAliases(td, i, as) ) {
+ common = createsPotentialAliases(td, i, as);
+ if( !common.isEmpty() ) {
foundSomeAlias = true;
bw.write("Potential alias between parameter "+i+" and "+as.getFlatNew()+".\n");
+ bw.write(prettyPrintNodeSet( common )+"\n" );
}
}
}
Iterator allocItr2 = allocSites.iterator();
while( allocItr2.hasNext() ) {
AllocationSite as2 = (AllocationSite) allocItr2.next();
+
+ if( !outerChecked.contains(as2) ) {
+ common = createsPotentialAliases(td, as1, as2);
- if( !outerChecked.contains(as2) &&
- createsPotentialAliases(td, as1, as2) ) {
- foundSomeAlias = true;
- bw.write("Potential alias between "+as1.getFlatNew()+" and "+as2.getFlatNew()+".\n");
+ if( !common.isEmpty() ) {
+ foundSomeAlias = true;
+ bw.write("Potential alias between "+as1.getFlatNew()+" and "+as2.getFlatNew()+".\n");
+ bw.write(prettyPrintNodeSet( common )+"\n" );
+ }
}
}
while( allocItr2.hasNext() ) {
AllocationSite as2 = (AllocationSite) allocItr2.next();
- if( !outerChecked.contains(as2) &&
- createsPotentialAliases(d, as1, as2) ) {
- foundSomeAlias = true;
- bw.write("Potential alias between "+as1.getDisjointId()+" and "+as2.getDisjointId()+".\n");
+ if( !outerChecked.contains(as2) ) {
+ Set<HeapRegionNode> common = createsPotentialAliases(d, as1, as2);
+
+ if( !common.isEmpty() ) {
+ foundSomeAlias = true;
+ bw.write("Potential alias between "+as1.getDisjointId()+" and "+as2.getDisjointId()+".\n");
+ bw.write( prettyPrintNodeSet( common )+"\n" );
+ }
}
}
}
- public boolean hasPotentialAlias( HeapRegionNode hrn1, HeapRegionNode hrn2 ) {
+ public Set<HeapRegionNode> hasPotentialAlias( HeapRegionNode hrn1, HeapRegionNode hrn2 ) {
assert hrn1 != null;
assert hrn2 != null;
beta2 = beta2.union( edge.getBeta() );
}
+ boolean aliasDetected = false;
+
// only do this one if they are different tokens
if( h1 != h2 &&
beta1.containsTupleSetWithBoth(h1, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1plus, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1star, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1plus, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1star, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1, h2star) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1plus, h2star) ) {
- return true;
+ aliasDetected = true;
}
if( beta1.containsTupleSetWithBoth(h1star, h2star) ) {
- return true;
+ aliasDetected = true;
}
if( h1 != h2 &&
beta2.containsTupleSetWithBoth(h1, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1plus, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1star, h2) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1plus, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1star, h2plus) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1, h2star) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1plus, h2star) ) {
- return true;
+ aliasDetected = true;
}
if( beta2.containsTupleSetWithBoth(h1star, h2star) ) {
- return true;
+ aliasDetected = true;
}
- return false;
+ Set<HeapRegionNode> common = new HashSet<HeapRegionNode>();
+ if( aliasDetected ) {
+ common = findCommonReachableNodes( hrn1, hrn2 );
+ assert !common.isEmpty();
+ }
+
+ return common;
}
- public boolean hasPotentialAlias(Integer paramIndex1, Integer paramIndex2) {
+ public Set<HeapRegionNode> hasPotentialAlias(Integer paramIndex1, Integer paramIndex2) {
// get parameter's heap region
assert paramIndex2id.containsKey(paramIndex1);
}
- public boolean hasPotentialAlias(Integer paramIndex, AllocationSite as) {
+ public Set<HeapRegionNode> hasPotentialAlias(Integer paramIndex, AllocationSite as) {
// get parameter's heap region
assert paramIndex2id.containsKey(paramIndex);
HeapRegionNode hrnSummary = id2hrn.get( as.getSummary() );
assert hrnSummary != null;
- if( hasPotentialAlias( hrnParam, hrnSummary ) ) {
- return true;
+ Set<HeapRegionNode> common = hasPotentialAlias( hrnParam, hrnSummary );
+ if( !common.isEmpty() ) {
+ return common;
}
// check for other nodes
HeapRegionNode hrnIthOldest = id2hrn.get( as.getIthOldest( i ) );
assert hrnIthOldest != null;
- if( hasPotentialAlias( hrnParam, hrnIthOldest ) ) {
- return true;
+ common = hasPotentialAlias( hrnParam, hrnIthOldest );
+ if( !common.isEmpty() ) {
+ return common;
}
}
- return false;
+ return new HashSet<HeapRegionNode>();
}
- public boolean hasPotentialAlias(AllocationSite as1, AllocationSite as2) {
-
+ public Set<HeapRegionNode> hasPotentialAlias(AllocationSite as1, AllocationSite as2) {
// get summary node 1's alpha
Integer idSum1 = as1.getSummary();
HeapRegionNode hrnSum2 = id2hrn.get(idSum2);
assert hrnSum2 != null;
- if( hasPotentialAlias( hrnSum1, hrnSum2 ) ) {
- return true;
+ Set<HeapRegionNode> common = hasPotentialAlias( hrnSum1, hrnSum2 );
+ if( !common.isEmpty() ) {
+ return common;
}
// check sum2 against alloc1 nodes
HeapRegionNode hrnI1 = id2hrn.get(idI1);
assert hrnI1 != null;
- if( hasPotentialAlias( hrnI1, hrnSum2 ) ) {
- return true;
+ common = hasPotentialAlias( hrnI1, hrnSum2 );
+ if( !common.isEmpty() ) {
+ return common;
}
}
HeapRegionNode hrnI2 = id2hrn.get(idI2);
assert hrnI2 != null;
- if( hasPotentialAlias( hrnSum1, hrnI2 ) ) {
- return true;
+ common = hasPotentialAlias( hrnSum1, hrnI2 );
+ if( common.isEmpty() ) {
+ return common;
}
// while we're at it, do an inner loop for alloc2 vs alloc1 nodes
HeapRegionNode hrnI1 = id2hrn.get(idI1);
- if( hasPotentialAlias( hrnI1, hrnI2 ) ) {
- return true;
+ common = hasPotentialAlias( hrnI1, hrnI2 );
+ if( !common.isEmpty() ) {
+ return common;
}
}
}
- return false;
+ return new HashSet<HeapRegionNode>();
+ }
+
+
+ public Set<HeapRegionNode> findCommonReachableNodes( HeapRegionNode hrn1,
+ HeapRegionNode hrn2 ) {
+
+ Set<HeapRegionNode> reachableNodes1 = new HashSet<HeapRegionNode>();
+ Set<HeapRegionNode> reachableNodes2 = new HashSet<HeapRegionNode>();
+
+ Set<HeapRegionNode> todoNodes1 = new HashSet<HeapRegionNode>();
+ todoNodes1.add( hrn1 );
+
+ Set<HeapRegionNode> todoNodes2 = new HashSet<HeapRegionNode>();
+ todoNodes2.add( hrn2 );
+
+ // follow links until all reachable nodes have been found
+ while( !todoNodes1.isEmpty() ) {
+ HeapRegionNode hrn = todoNodes1.iterator().next();
+ todoNodes1.remove( hrn );
+ reachableNodes1.add(hrn);
+
+ Iterator<ReferenceEdge> edgeItr = hrn.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ ReferenceEdge edge = edgeItr.next();
+
+ if( !reachableNodes1.contains( edge.getDst() ) ) {
+ todoNodes1.add( edge.getDst() );
+ }
+ }
+ }
+
+ while( !todoNodes2.isEmpty() ) {
+ HeapRegionNode hrn = todoNodes2.iterator().next();
+ todoNodes2.remove( hrn );
+ reachableNodes2.add(hrn);
+
+ Iterator<ReferenceEdge> edgeItr = hrn.iteratorToReferencees();
+ while( edgeItr.hasNext() ) {
+ ReferenceEdge edge = edgeItr.next();
+
+ if( !reachableNodes2.contains( edge.getDst() ) ) {
+ todoNodes2.add( edge.getDst() );
+ }
+ }
+ }
+
+ Set<HeapRegionNode> intersection =
+ new HashSet<HeapRegionNode>( reachableNodes1 );
+
+ intersection.retainAll( reachableNodes2 );
+
+ return intersection;
}
import Analysis.TaskStateAnalysis.SafetyAnalysis;
import Analysis.OwnershipAnalysis.AllocationSite;
import Analysis.OwnershipAnalysis.OwnershipAnalysis;
+import Analysis.OwnershipAnalysis.HeapRegionNode;
import Analysis.Prefetch.*;
import IR.ClassDescriptor;
import IR.Descriptor;
Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
+ Set<HeapRegionNode> common;
for( int i = 0; i < fm.numParameters(); ++i ) {
// for the ith parameter check for aliases to all
// higher numbered parameters
aliasSets.add(null);
for( int j = i + 1; j < fm.numParameters(); ++j ) {
- if(this.m_oa.createsPotentialAliases(td, i, j)) {
+ common = this.m_oa.createsPotentialAliases(td, i, j);
+ if(!common.isEmpty()) {
// ith parameter and jth parameter has alias, create lock to protect them
if(aliasSets.elementAt(i) == null) {
aliasSets.setElementAt(new Vector<Integer>(), i);
aliasFNSets.add(null);
for(int j = 0; j < allocSites.length; j++) {
AllocationSite as = (AllocationSite)allocSites[j];
- if( this.m_oa.createsPotentialAliases(td, i, as) ) {
+ common = this.m_oa.createsPotentialAliases(td, i, as);
+ if( !common.isEmpty() ) {
// ith parameter and allocationsite as has alias
if(aliasFNSets.elementAt(i) == null) {
aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
for(int j = i + 1; j < allocSites.length; j++) {
AllocationSite as2 = (AllocationSite)allocSites[j];
- if( this.m_oa.createsPotentialAliases(td, as1, as2) ) {
+ common = this.m_oa.createsPotentialAliases(td, as1, as2);
+ if( !common.isEmpty() ) {
// as1 and as2 has alias
if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());