bw.close();
}
+
+ // this version of writeAllAliases is for Java programs that have no tasks
+ public void writeAllAliasesJava(String outputFile) throws java.io.IOException {
+ assert !state.TASK;
+
+ BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile) );
+
+ bw.write("Conducting ownership analysis with allocation depth = "+allocationDepth+"\n");
+ boolean foundSomeAlias = false;
+
+ Descriptor d = typeUtil.getMain();
+ HashSet<AllocationSite> allocSites = getFlaggedAllocationSites(d);
+
+ // for each allocation site check for aliases with
+ // other allocation sites in the context of execution
+ // of this task
+ HashSet<AllocationSite> outerChecked = new HashSet<AllocationSite>();
+ Iterator allocItr1 = allocSites.iterator();
+ while( allocItr1.hasNext() ) {
+ AllocationSite as1 = (AllocationSite) allocItr1.next();
+
+ Iterator allocItr2 = allocSites.iterator();
+ 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");
+ }
+ }
+
+ outerChecked.add(as1);
+ }
+
+ if( !foundSomeAlias ) {
+ bw.write("No aliases between flagged objects found.\n");
+ }
+
+ bw.close();
+ }
///////////////////////////////////////////
//
// end public interface
} else {
// we are not in task mode, just normal Java, so start with
// the main method
- Descriptor d = tu.getMain();
+ Descriptor d = typeUtil.getMain();
scheduleAllCallees(d);
-
- /*
- Iterator classItr = state.getClassSymbolTable().getDescriptorsIterator();
- while( classItr.hasNext() ) {
- ClassDescriptor cd = (ClassDescriptor) classItr.next();
-
- Iterator methItr = cd.getMethods();
- while( methItr.hasNext() ) {
- Descriptor d = (Descriptor) methItr.next();
-
- if( d.getSymbol().equals( "main" ) ) {
- scheduleAllCallees(d);
- }
- }
- }
- */
}
System.out.println( treport );
if( aliasFile != null ) {
- writeAllAliases(aliasFile);
+ if( state.TASK ) {
+ writeAllAliases(aliasFile);
+ } else {
+ writeAllAliasesJava(aliasFile);
+ }
}
}
}
+ private HashSet<AllocationSite> getFlaggedAllocationSites(Descriptor d) {
+
+ HashSet<AllocationSite> out = new HashSet<AllocationSite>();
+
+ HashSet<AllocationSite> asSet = getAllocationSiteSet(d);
+ Iterator asItr = asSet.iterator();
+ while( asItr.hasNext() ) {
+ AllocationSite as = (AllocationSite) asItr.next();
+ if( as.getDisjointId() != null ) {
+ out.add(as);
+ }
+ }
+
+ return out;
+ }
+
+
private HashSet<AllocationSite>
getFlaggedAllocationSitesReachableFromTaskPRIVATE(TaskDescriptor td) {
return id2paramIndexSet.size() == og.id2paramIndexSet.size();
}
+
+ public boolean hasPotentialAlias( HeapRegionNode hrn1, HeapRegionNode hrn2 ) {
+ assert hrn1 != null;
+ assert hrn2 != null;
+
+ // then get the various tokens for these heap regions
+ TokenTuple h1 = new TokenTuple(hrn1.getID(),
+ !hrn1.isSingleObject(),
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple h1plus = new TokenTuple(hrn1.getID(),
+ !hrn1.isSingleObject(),
+ TokenTuple.ARITY_ONEORMORE).makeCanonical();
+
+ TokenTuple h1star = new TokenTuple(hrn1.getID(),
+ !hrn1.isSingleObject(),
+ TokenTuple.ARITY_ZEROORMORE).makeCanonical();
+
+ TokenTuple h2 = new TokenTuple(hrn2.getID(),
+ !hrn2.isSingleObject(),
+ TokenTuple.ARITY_ONE).makeCanonical();
+
+ TokenTuple h2plus = new TokenTuple(hrn2.getID(),
+ !hrn2.isSingleObject(),
+ TokenTuple.ARITY_ONEORMORE).makeCanonical();
+
+ TokenTuple h2star = new TokenTuple(hrn2.getID(),
+ !hrn2.isSingleObject(),
+ TokenTuple.ARITY_ZEROORMORE).makeCanonical();
+
+ // then get the merged beta of all out-going edges from these heap regions
+ ReachabilitySet beta1 = new ReachabilitySet();
+ Iterator<ReferenceEdge> itrEdge = hrn1.iteratorToReferencees();
+ while( itrEdge.hasNext() ) {
+ ReferenceEdge edge = itrEdge.next();
+ beta1 = beta1.union( edge.getBeta() );
+ }
+
+ ReachabilitySet beta2 = new ReachabilitySet();
+ itrEdge = hrn2.iteratorToReferencees();
+ while( itrEdge.hasNext() ) {
+ ReferenceEdge edge = itrEdge.next();
+ beta2 = beta2.union( edge.getBeta() );
+ }
+
+ // only do this one if they are different tokens
+ if( h1 != h2 &&
+ beta1.containsTupleSetWithBoth(h1, h2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1plus, h2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1star, h2) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1, h2plus) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1plus, h2plus) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1star, h2plus) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1, h2star) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1plus, h2star) ) {
+ return true;
+ }
+ if( beta1.containsTupleSetWithBoth(h1star, h2star) ) {
+ return true;
+ }
+
+ if( h1 != h2 &&
+ beta2.containsTupleSetWithBoth(h1, h2) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1plus, h2) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1star, h2) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1, h2plus) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1plus, h2plus) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1star, h2plus) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1, h2star) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1plus, h2star) ) {
+ return true;
+ }
+ if( beta2.containsTupleSetWithBoth(h1star, h2star) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+
public boolean hasPotentialAlias(Integer paramIndex1, Integer paramIndex2) {
// get parameter's heap region
HeapRegionNode hrnParam1 = id2hrn.get(idParam1);
assert hrnParam1 != null;
+ /*
// get tokens for this parameter
TokenTuple p1 = new TokenTuple(hrnParam1.getID(),
true,
TokenTuple pStar1 = new TokenTuple(hrnParam1.getID(),
true,
TokenTuple.ARITY_ZEROORMORE).makeCanonical();
-
+ */
// get tokens for the other parameter
assert paramIndex2id.containsKey(paramIndex2);
HeapRegionNode hrnParam2 = id2hrn.get(idParam2);
assert hrnParam2 != null;
+
+ return hasPotentialAlias( hrnParam1, hrnParam2 );
+
+
+ /*
+
TokenTuple p2 = new TokenTuple(hrnParam2.getID(),
true,
TokenTuple.ARITY_ONE).makeCanonical();
if( beta1.containsTupleSetWithBoth(pStar1, pStar2) ) {
return true;
}
-
+
return false;
+ */
}
HeapRegionNode hrnParam = id2hrn.get(idParam);
assert hrnParam != null;
+
+ /*
// get tokens for this parameter
TokenTuple p = new TokenTuple(hrnParam.getID(),
true,
// look through this beta set for potential aliases
ReachabilitySet beta = edgeSpecialQ.getBeta();
assert beta != null;
-
+
// get tokens for summary node
TokenTuple gs = new TokenTuple(as.getSummary(),
if( beta.containsTupleSetWithBoth(pStar, gsStar) ) {
return true;
}
+ */
+
+ assert id2hrn.containsKey( as.getSummary() );
+ HeapRegionNode hrnSummary = id2hrn.get( as.getSummary() );
+ assert hrnSummary != null;
+ if( hasPotentialAlias( hrnParam, hrnSummary ) ) {
+ return true;
+ }
// check for other nodes
for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+ assert id2hrn.containsKey( as.getIthOldest( i ) );
+ HeapRegionNode hrnIthOldest = id2hrn.get( as.getIthOldest( i ) );
+ assert hrnIthOldest != null;
+ if( hasPotentialAlias( hrnParam, hrnIthOldest ) ) {
+ return true;
+ }
+
+
+ /*
// the other nodes of an allocation site are single, no plus
TokenTuple gi = new TokenTuple(as.getIthOldest(i),
false,
if( beta.containsTupleSetWithBoth(pStar, giStar) ) {
return true;
}
+ */
}
- return false;
+ return false;
}
public boolean hasPotentialAlias(AllocationSite as1, AllocationSite as2) {
-
+ /*
// get tokens for summary nodes
TokenTuple gs1 = new TokenTuple(as1.getSummary(),
true,
TokenTuple gsStar1 = new TokenTuple(as1.getSummary(),
true,
TokenTuple.ARITY_ZEROORMORE).makeCanonical();
+ */
// get summary node's alpha
Integer idSum1 = as1.getSummary();
assert id2hrn.containsKey(idSum1);
HeapRegionNode hrnSum1 = id2hrn.get(idSum1);
assert hrnSum1 != null;
+
+ /*
ReachabilitySet alphaSum1 = hrnSum1.getAlpha();
assert alphaSum1 != null;
-
+
// and for the other one
TokenTuple gs2 = new TokenTuple(as2.getSummary(),
TokenTuple gsStar2 = new TokenTuple(as2.getSummary(),
true,
TokenTuple.ARITY_ZEROORMORE).makeCanonical();
+ */
// get summary node's alpha
Integer idSum2 = as2.getSummary();
assert id2hrn.containsKey(idSum2);
HeapRegionNode hrnSum2 = id2hrn.get(idSum2);
assert hrnSum2 != null;
+
+ if( hasPotentialAlias( hrnSum1, hrnSum2 ) ) {
+ return true;
+ }
+
+ /*
ReachabilitySet alphaSum2 = hrnSum2.getAlpha();
assert alphaSum2 != null;
+
// does either one report reachability from the other tokens?
if( alphaSum1.containsTuple(gsPlus2) ) {
return true;
return true;
}
}
-
+ */
// check sum2 against alloc1 nodes
for( int i = 0; i < as1.getAllocationDepth(); ++i ) {
assert id2hrn.containsKey(idI1);
HeapRegionNode hrnI1 = id2hrn.get(idI1);
assert hrnI1 != null;
+
+ if( hasPotentialAlias( hrnI1, hrnSum2 ) ) {
+ return true;
+ }
+
+ /*
ReachabilitySet alphaI1 = hrnI1.getAlpha();
assert alphaI1 != null;
+
// the other nodes of an allocation site are single, no stars
TokenTuple gi1 = new TokenTuple(as1.getIthOldest(i),
false,
if( alphaI1.containsTuple(gsStar2) ) {
return true;
}
+ */
}
// check sum1 against alloc2 nodes
assert id2hrn.containsKey(idI2);
HeapRegionNode hrnI2 = id2hrn.get(idI2);
assert hrnI2 != null;
+
+ if( hasPotentialAlias( hrnSum1, hrnI2 ) ) {
+ return true;
+ }
+
+ /*
ReachabilitySet alphaI2 = hrnI2.getAlpha();
assert alphaI2 != null;
if( alphaI2.containsTuple(gsStar1) ) {
return true;
}
+ */
// while we're at it, do an inner loop for alloc2 vs alloc1 nodes
for( int j = 0; j < as1.getAllocationDepth(); ++j ) {
}
HeapRegionNode hrnI1 = id2hrn.get(idI1);
+
+ if( hasPotentialAlias( hrnI1, hrnI2 ) ) {
+ return true;
+ }
+
+ /*
ReachabilitySet alphaI1 = hrnI1.getAlpha();
TokenTuple gi1 = new TokenTuple(as1.getIthOldest(j),
false,
if( alphaI1.containsTuple(giStar2) ) {
return true;
}
+ */
}
}