--- /dev/null
+package Analysis.OwnershipAnalysis;
+
+import IR.*;
+import IR.Flat.*;
+import java.util.*;
+import java.io.*;
+
+public class Canonical {
+
+ private static Hashtable<Canonical, Canonical> canon = new Hashtable<Canonical, Canonical>();
+
+ public static Canonical makeCanonical( Canonical c ) {
+ if( canon.containsKey( c ) ) {
+ return canon.get( c );
+ }
+
+ canon.put( c, c );
+ return c;
+ }
+}
// THIS CLASS IS IMMUTABLE!
-public class ChangeTuple
+public class ChangeTuple extends Canonical
{
private TokenTupleSet toMatch;
private TokenTupleSet toAdd;
this.toAdd = toAdd;
}
+ public ChangeTuple makeCanonical() {
+ return (ChangeTuple) Canonical.makeCanonical( this );
+ }
+
public TokenTupleSet getSetToMatch() { return toMatch; }
public TokenTupleSet getSetToAdd() { return toAdd; }
import java.io.*;
-public class ChangeTupleSet {
+public class ChangeTupleSet extends Canonical {
private HashSet<ChangeTuple> changeTuples;
changeTuples = (HashSet<ChangeTuple>) cts.changeTuples.clone(); //COPY?!
}
+ public ChangeTupleSet makeCanonical() {
+ return (ChangeTupleSet) Canonical.makeCanonical( this );
+ }
+
public Iterator iterator() {
return changeTuples.iterator();
}
public ChangeTupleSet union( ChangeTupleSet ctsIn ) {
ChangeTupleSet ctsOut = new ChangeTupleSet( this );
ctsOut.changeTuples.addAll( ctsIn.changeTuples );
- return ctsOut;
+ return ctsOut.makeCanonical();
}
public boolean isSubset( ChangeTupleSet ctsIn ) {
return ctsIn.changeTuples.containsAll( this.changeTuples );
}
+ public boolean equals( Object o ) {
+ if( !(o instanceof ChangeTupleSet) ) {
+ return false;
+ }
+
+ ChangeTupleSet cts = (ChangeTupleSet) o;
+ return changeTuples.equals( cts.changeTuples );
+ }
+
+ public int hashCode() {
+ return changeTuples.hashCode();
+ }
+
public String toString() {
String s = "[";
return id;
}
+
public boolean equals( HeapRegionNode hrn ) {
assert hrn != null;
isSingleObject == hrn.isSingleObject() &&
isFlagged == hrn.isFlagged() &&
isNewSummary == hrn.isNewSummary() &&
+ alpha.equals( hrn.getAlpha() ) &&
description.equals( hrn.getDescription() );
}
}
+ public void setAlpha( ReachabilitySet alpha ) {
+ this.alpha = alpha;
+ }
+
public ReachabilitySet getAlpha() {
return alpha;
}
// the final ownership graph result to return as an empty set
returnNodesToCombineForCompleteOwnershipGraph = new HashSet<FlatReturnNode>();
+
+ // DEBUG
+ //int x = 0;
+
+
while( !flatNodesToVisit.isEmpty() ) {
FlatNode fn = (FlatNode) flatNodesToVisit.iterator().next();
flatNodesToVisit.remove( fn );
if( !og.equals( ogPrev ) ) {
setGraphForFlatNode( fn, og );
+ // DEBUG
+ /*
+ ++x;
+
+ if( x > 5000 ) {
+ String s = String.format( "%04d", x );
+ og.writeGraph( "debug"+s, false, false );
+ }
+
+ if( x == 5020 ) {
+ System.exit( -1 );
+ }
+ */
+
for( int i = 0; i < fn.numNext(); i++ ) {
FlatNode nn = fn.getNext( i );
flatNodesToVisit.add( nn );
public HashSet<AllocationSite> allocationSites;
- // CHANGE! Map HRN ID's to token sets (sets of IDs!)
- //public Hashtable< HeapRegionNode, HashSet< HashSet<HeapRegionNode> > > alpha;
- //public Hashtable< touple< HRN, HRN >, HashSet< HashSet<HeapRegionNode> > > beta;
-
public OwnershipGraph( int allocationDepth ) {
this.allocationDepth = allocationDepth;
paramIndex2id = new Hashtable<Integer, Integer >();
allocationSites = new HashSet <AllocationSite>();
-
- //alpha = new Hashtable< HeapRegionNode, HashSet< HashSet<HeapRegionNode> > >();
}
// in merge() and equals() methods the suffix A
// represents the passed in graph and the suffix
// B refers to the graph in this object
+ // Merging means to take the incoming graph A and
+ // merge it into B, so after the operation graph B
+ // is the final result.
////////////////////////////////////////////////////
public void merge( OwnershipGraph og ) {
mergeReferenceEdges ( og );
mergeId2paramIndex ( og );
mergeAllocationSites( og );
- //mergeTokenSets ( og );
}
+
protected void mergeOwnershipNodes( OwnershipGraph og ) {
Set sA = og.id2hrn.entrySet();
Iterator iA = sA.iterator();
if( !id2hrn.containsKey( idA ) ) {
HeapRegionNode hrnB = hrnA.copy();
id2hrn.put( idA, hrnB );
+ } else {
+ // otherwise this is a node present in both graphs
+ // so make the new reachability set a union of the
+ // nodes' reachability sets
+ HeapRegionNode hrnB = id2hrn.get( idA );
+ hrnB.setAlpha( hrnB.getAlpha().union( hrnA.getAlpha() ) );
}
}
// for stroing heap region nodes retrieved by integer
// ids. Because finding edges requires interacting
// with these disparate data structures frequently the
- // process is nearly duplicated, one for each
+ // process is nearly duplicated, one for each structure
+ // that stores edges
// heap regions
Set sA = og.id2hrn.entrySet();
assert id2hrn.containsKey( idA );
HeapRegionNode hrnB = id2hrn.get( idA );
- HeapRegionNode hrnChildB = null;
+ HeapRegionNode hrnChildB = null;
+ ReferenceEdgeProperties repB = null;
Iterator heapRegionsItrB = hrnB.setIteratorToReferencedRegions();
while( heapRegionsItrB.hasNext() ) {
- Map.Entry meC = (Map.Entry) heapRegionsItrB.next();
- hrnChildB = (HeapRegionNode) meC.getKey();
+ Map.Entry meC = (Map.Entry) heapRegionsItrB.next();
+ hrnChildB = (HeapRegionNode) meC.getKey();
+ ReferenceEdgeProperties rep = (ReferenceEdgeProperties) meC.getValue();
if( hrnChildB.equals( idChildA ) ) {
edgeFound = true;
+ repB = rep;
}
}
if( !edgeFound ) {
assert id2hrn.containsKey( idChildA );
hrnChildB = id2hrn.get( idChildA );
- ReferenceEdgeProperties repB = repA.copy();
+ repB = repA.copy();
addReferenceEdge( hrnB, hrnChildB, repB );
}
- // otherwise, the edge already existed in both graphs.
- // if this is the case, check to see whether the isUnique
- // predicate of the edges might change
- else
- {
-
+ // otherwise, the edge already existed in both graphs
+ // so merge their reachability sets
+ else {
+ // just replace this beta set with the union
+ assert repB != null;
+ repB.setBeta( repB.getBeta().union( repA.getBeta() ) );
}
}
}
assert td2ln.containsKey( tdA );
LabelNode lnB = td2ln.get( tdA );
- HeapRegionNode hrnChildB = null;
+ HeapRegionNode hrnChildB = null;
+ ReferenceEdgeProperties repB = null;
Iterator heapRegionsItrB = lnB.setIteratorToReferencedRegions();
while( heapRegionsItrB.hasNext() ) {
- Map.Entry meC = (Map.Entry) heapRegionsItrB.next();
- hrnChildB = (HeapRegionNode) meC.getKey();
+ Map.Entry meC = (Map.Entry) heapRegionsItrB.next();
+ hrnChildB = (HeapRegionNode) meC.getKey();
+ ReferenceEdgeProperties rep = (ReferenceEdgeProperties) meC.getValue();
if( hrnChildB.equals( idChildA ) ) {
edgeFound = true;
+ repB = rep;
}
}
if( !edgeFound ) {
assert id2hrn.containsKey( idChildA );
hrnChildB = id2hrn.get( idChildA );
- ReferenceEdgeProperties repB = repA.copy();
+ repB = repA.copy();
addReferenceEdge( lnB, hrnChildB, repB );
}
- // otherwise, the edge already existed in both graphs.
- // if this is the case, check to see whether the isUnique
- // predicate of the edges might change
- else
- {
-
+ // otherwise, the edge already existed in both graphs
+ // so merge the reachability sets
+ else {
+ // just replace this beta set with the union
+ assert repB != null;
+ repB.setBeta( repB.getBeta().union( repA.getBeta() ) );
}
}
}
}
-
- //protected void mergeTokenSets( OwnershipGraph og ) {
- // alpha = new Hashtable< HeapRegionNode, HashSet< HashSet<HeapRegionNode> > >();
-
- // if a key is in one or the other token set,
- // add it to the merged token set.
- // if a key is in both graphs, the merged
- // token set should have that key and the union
- // of values as the merged value.
-
- /*
- Set alphaB = og.alpha.entrySet();
- Iterator iB = alphaB.iterator();
- while( iB.hasNext() ) {
- Map.Entry meB = (Map.Entry) iB.next();
- HeapRegionNode hrnKeyB = (HeapRegionNode) meB.getKey();
- HashSet< HashSet<HeapRegionNode> > > tokenSetsB =
- (HashSet< HashSet<HeapRegionNode> > >) meB.getValue();
-
- if( !alpha.containsKey( hrnKeyB ) ) {
- alpha.put( hrnKeyB, tokenSetsB );
- } else {
-
- }
- }
- */
- //}
-
-
-
-
-
// it is necessary in the equals() member functions
// to "check both ways" when comparing the data
return false;
}
- HeapRegionNode hrnB = og.id2hrn.get( idA );
+ //HeapRegionNode hrnB = og.id2hrn.get( idA );
+ HeapRegionNode hrnB = id2hrn.get( idA );
if( !hrnA.equals( hrnB ) ) {
return false;
}
import java.io.*;
-public class ReachabilitySet {
+public class ReachabilitySet extends Canonical {
private HashSet<TokenTupleSet> possibleReachabilities;
possibleReachabilities = (HashSet<TokenTupleSet>) rs.possibleReachabilities.clone(); // again, DEEP COPY?!
}
+ public ReachabilitySet makeCanonical() {
+ return (ReachabilitySet) Canonical.makeCanonical( this );
+ }
+
public Iterator iterator() {
return possibleReachabilities.iterator();
}
public ReachabilitySet union( ReachabilitySet rsIn ) {
ReachabilitySet rsOut = new ReachabilitySet( this );
rsOut.possibleReachabilities.addAll( rsIn.possibleReachabilities );
- return rsOut;
+ return rsOut.makeCanonical();
}
public ReachabilitySet intersection( ReachabilitySet rsIn ) {
}
}
- return rsOut;
+ return rsOut.makeCanonical();
}
public ChangeTupleSet unionUpArity( ReachabilitySet rsIn ) {
TokenTuple e = (TokenTuple) itrRelement.next();
if( o.containsToken( e.getToken() ) ) {
- theUnion = theUnion.union( new TokenTupleSet( e.increaseArity() ) );
+ theUnion = theUnion.union( new TokenTupleSet( e.increaseArity() ) ).makeCanonical();
} else {
- theUnion = theUnion.union( new TokenTupleSet( e ) );
+ theUnion = theUnion.union( new TokenTupleSet( e ) ).makeCanonical();
}
}
TokenTuple e = (TokenTuple) itrOelement.next();
if( !theUnion.containsToken( e.getToken() ) ) {
- theUnion = theUnion.union( new TokenTupleSet( e ) );
+ theUnion = theUnion.union( new TokenTupleSet( e ) ).makeCanonical();
}
}
}
}
- return ctsOut;
+ return ctsOut.makeCanonical();
+ }
+
+
+ public boolean equals( Object o ) {
+ if( !(o instanceof ReachabilitySet) ) {
+ return false;
+ }
+
+ ReachabilitySet rs = (ReachabilitySet) o;
+ return possibleReachabilities.equals( rs.possibleReachabilities );
+ }
+
+ public int hashCode() {
+ return possibleReachabilities.hashCode();
}
return s;
}
-
public String toString() {
String s = "[";
public ReferenceEdgeProperties() {
this.isUnique = false;
this.isInitialParamReflexive = false;
+ this.beta = new ReachabilitySet();
}
public ReferenceEdgeProperties( boolean isUnique ) {
this.isUnique = isUnique;
this.isInitialParamReflexive = false;
+ this.beta = new ReachabilitySet();
}
public ReferenceEdgeProperties( boolean isUnique,
boolean isInitialParamReflexive ) {
this.isUnique = isUnique;
this.isInitialParamReflexive = isInitialParamReflexive;
+ this.beta = new ReachabilitySet();
+ }
+
+ public ReferenceEdgeProperties( boolean isUnique,
+ boolean isInitialParamReflexive,
+ ReachabilitySet beta) {
+ this.isUnique = isUnique;
+ this.isInitialParamReflexive = isInitialParamReflexive;
+ this.beta = beta;
}
}
+ protected ReachabilitySet beta;
+ public ReachabilitySet getBeta() {
+ return beta;
+ }
+ public void setBeta( ReachabilitySet beta ) {
+ this.beta = beta;
+ }
+ public String getBetaString() {
+ return beta.toStringEscapeNewline();
+ }
+
+
public boolean equals( ReferenceEdgeProperties rep ) {
return isUnique == rep.isUnique() &&
isInitialParamReflexive == rep.isInitialParamReflexive();
// THIS CLASS IS IMMUTABLE!
-public class TokenTuple
+public class TokenTuple extends Canonical
{
private Integer token;
private boolean isNewSummary;
this.arity = arity;
}
+ public TokenTuple makeCanonical() {
+ return (TokenTuple) Canonical.makeCanonical( this );
+ }
+
public Integer getToken() { return token; }
public int getArity() { return arity; }
public TokenTuple increaseArity() {
if( isNewSummary ) {
- return new TokenTuple( token, isNewSummary, ARITY_MANY );
+ return (TokenTuple) Canonical.makeCanonical(
+ new TokenTuple( token, isNewSummary, ARITY_MANY )
+ );
}
return this;
}
import java.io.*;
-public class TokenTupleSet {
+public class TokenTupleSet extends Canonical {
private HashSet<TokenTuple> tokenTuples;
tokenTuples = (HashSet<TokenTuple>) tts.tokenTuples.clone(); //COPY?!
}
+ public TokenTupleSet makeCanonical() {
+ return (TokenTupleSet) Canonical.makeCanonical( this );
+ }
+
public Iterator iterator() {
return tokenTuples.iterator();
}
public TokenTupleSet union( TokenTupleSet ttsIn ) {
TokenTupleSet ttsOut = new TokenTupleSet( this );
ttsOut.tokenTuples.addAll( ttsIn.tokenTuples );
- return ttsOut;
+ return ttsOut.makeCanonical();
}
public boolean isEmpty() {
return tokenTuples.contains( tt );
}
+ public boolean equals( Object o ) {
+ if( !(o instanceof TokenTupleSet) ) {
+ return false;
+ }
+
+ TokenTupleSet tts = (TokenTupleSet) o;
+ return tokenTuples.equals( tts.tokenTuples );
+ }
+
+ public int hashCode() {
+ return tokenTuples.hashCode();
+ }
+
// this should be a hash table so we can do this by key
public boolean containsToken( Integer token ) {
Iterator itr = tokenTuples.iterator();
Analysis/OwnershipAnalysis/ReachabilitySet.class \
Analysis/OwnershipAnalysis/ChangeTuple.class \
Analysis/OwnershipAnalysis/ChangeTupleSet.class \
+Analysis/OwnershipAnalysis/Canonical.class \
Util/GraphNode.class Util/Namer.class Util/Relation.class \
Interface/HTTPHeader.class Interface/HTTPResponse.class \
Interface/HTTPServices.class Interface/HashStrings.class \
#eog *FN*.png &
#eog *Ownership*.png &
eog *COMPLETE*.png &
+ #eog *debug*.png &
printable:
rm -f *Startup*.dot
PNGs: DOTs
#rm -f *Startup*.dot
+ #rm -f *COMPLETE*.dot
+ rm -f *FlatIR*.dot
rm -f *FlatMethod*.dot
rm -f *FlatOpNode*.dot
rm -f *FlatFieldNode*.dot
}
-
+/*
// this task allocates a new object, so there should
// be a heap region for the parameter, and several
// heap regions for the allocation site, but the label
taskexit( v{ !f } );
}
+
// this task
task Branch( Voo v{ f } ) {
Voo w = new Voo();
taskexit( v{ !f } );
}
-
+*/
task NoAliasNewInLoop( Voo v{ f } ) {
taskexit( v{ !f } );
}
+/*
task NoAliasNewInLoopAnotherWay( Voo v{ f } ) {
for( int i = 0; i < 10; ++i ) {
taskexit( v{ !f }, w{ !f } );
}
+*/
\ No newline at end of file
public static void main(String args[]) throws Exception {
+
// example test to know the testing routine is correct!
test( "4 == 5?", false, 4 == 5 );
test( "3 == 3?", true, 3 == 3 );
true,
TokenTuple.ARITY_ONE );
- /* TokenTuple tt5 = new TokenTuple( new Integer( 4 ),
- true,
+ TokenTuple tt5 = new TokenTuple( new Integer( 4 ),
+ true,
TokenTuple.ARITY_ONE );
- */
+
TokenTuple tt6 = new TokenTuple( new Integer( 6 ),
false,
TokenTuple.ARITY_ONE );
ChangeTupleSet cts0 = rs0.unionUpArity( rs1 );
System.out.println( "cts0 is "+cts0 );
+
+
+
+ TokenTuple tt00 = new TokenTuple( new Integer( 9 ),
+ true,
+ TokenTuple.ARITY_ONE );
+
+ TokenTuple tt01 = new TokenTuple( new Integer( 9 ),
+ true,
+ TokenTuple.ARITY_ONE );
+
+ test( "tt00 equals tt01?", true, tt00.equals( tt01 ) );
+ test( "tt00 == tt01?", false, tt00 == tt01 );
+
+ tt00 = (TokenTuple) Canonical.makeCanonical( tt00 );
+ tt01 = (TokenTuple) Canonical.makeCanonical( tt01 );
+
+ test( "tt00 equals tt01?", true, tt00.equals( tt01 ) );
+ test( "tt00 == tt01?", true, tt00 == tt01 );
+
+
+ TokenTuple tt02 =
+ (TokenTuple) Canonical.makeCanonical(
+ new TokenTuple( new Integer( 10 ),
+ true,
+ TokenTuple.ARITY_ONE )
+ );
+
+ TokenTuple tt03 =
+ (TokenTuple) Canonical.makeCanonical(
+ new TokenTuple( new Integer( 11 ),
+ true,
+ TokenTuple.ARITY_ONE )
+ );
+
+ TokenTuple tt04 =
+ (TokenTuple) Canonical.makeCanonical(
+ new TokenTuple( new Integer( 12 ),
+ true,
+ TokenTuple.ARITY_ONE )
+ );
+
+ TokenTupleSet ttsT00 =
+ (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt00 ) );
+
+ TokenTupleSet ttsT01 =
+ (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt01 ) );
+
+ TokenTupleSet ttsT02 =
+ (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt02 ) );
+
+ TokenTupleSet ttsT03 =
+ (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt03 ) );
+
+ TokenTupleSet ttsT04 =
+ (TokenTupleSet) Canonical.makeCanonical( new TokenTupleSet( tt04 ) );
+
+ TokenTupleSet tts00 = ttsT00.union( ttsT02.union( ttsT03.union( ttsT04 ) ) );
+ TokenTupleSet tts01 = ttsT01.union( ttsT02.union( ttsT03.union( ttsT04 ) ) );
+
+ test( "tts00 equals tts01?", true, tts00.equals( tts01 ) );
+
+ // It's OK that this one turns out true--I changed the union operator
+ // to automatically canonicalize stuff!
+ test( "tts00 == tts01?", false, tts00 == tts01 );
+
+ tts00 = (TokenTupleSet) Canonical.makeCanonical( tts00 );
+ tts01 = (TokenTupleSet) Canonical.makeCanonical( tts01 );
+
+ test( "tts00 equals tts01?", true, tts00.equals( tts01 ) );
+ test( "tts00 == tts01?", true, tts00 == tts01 );
}
-}
\ No newline at end of file
+}