Break aging into smaller procedures and improve graphing for method call work.
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / OwnershipGraph.java
index cee91235777ddb6224dfbd490e1242106db11529..65b39c9345c91df262cb3cbca310d8b2de4d7030 100644 (file)
@@ -115,6 +115,8 @@ public class OwnershipGraph {
        assert rep        != null;
        referencer.addReferencedRegion( referencee, rep );
        referencee.addReferencer( referencer );
+       rep.setSrc( referencer );
+       rep.setDst( referencee );
     }
 
     protected void removeReferenceEdge( OwnershipNode  referencer,
@@ -156,9 +158,147 @@ public class OwnershipGraph {
     }
     
 
+    protected void propagateTokensOverNodes( HeapRegionNode                   nPrime,
+                                            ChangeTupleSet                   c0,
+                                            HashSet<HeapRegionNode>          nodesWithNewAlpha,
+                                            HashSet<ReferenceEdgeProperties> edgesWithNewBeta ) {      
 
-    protected void propagateTokens( HeapRegionNode nPrime, ChangeTupleSet c0 ) {
+       HashSet<HeapRegionNode> todoNodes
+           = new HashSet<HeapRegionNode>();
+       todoNodes.add( nPrime );
 
+       HashSet<ReferenceEdgeProperties> todoEdges 
+           = new HashSet<ReferenceEdgeProperties>();
+       
+       Hashtable<HeapRegionNode, ChangeTupleSet> nodePlannedChanges 
+           = new Hashtable<HeapRegionNode, ChangeTupleSet>();
+       nodePlannedChanges.put( nPrime, c0 );
+
+       Hashtable<ReferenceEdgeProperties, ChangeTupleSet> edgePlannedChanges 
+           = new Hashtable<ReferenceEdgeProperties, ChangeTupleSet>();
+       
+
+       while( !todoNodes.isEmpty() ) {
+           HeapRegionNode n = todoNodes.iterator().next();        
+           ChangeTupleSet C = nodePlannedChanges.get( n );
+
+           Iterator itrC = C.iterator();
+           while( itrC.hasNext() ) {
+               ChangeTuple c = (ChangeTuple) itrC.next();
+
+               if( n.getAlpha().contains( c.getSetToMatch() ) ) {
+                   ReachabilitySet withChange = n.getAlpha().union( c.getSetToAdd() );
+                   n.setAlphaNew( n.getAlphaNew().union( withChange ) );
+                   nodesWithNewAlpha.add( n );
+               }
+           }
+
+           Iterator referItr = n.iteratorToReferencers();
+           while( referItr.hasNext() ) {
+               OwnershipNode           on  = (OwnershipNode) referItr.next();
+               ReferenceEdgeProperties rep = on.getReferenceTo( n );
+               todoEdges.add( rep );
+
+               if( !edgePlannedChanges.containsKey( rep ) ) {
+                   edgePlannedChanges.put( rep, new ChangeTupleSet().makeCanonical() );
+               }
+
+               edgePlannedChanges.put( rep, edgePlannedChanges.get( rep ).union( C ) );
+           }
+
+           HeapRegionNode          m = null;
+           ReferenceEdgeProperties f = null;
+           Iterator refeeItr = n.setIteratorToReferencedRegions();
+           while( refeeItr.hasNext() ) {
+               Map.Entry me = (Map.Entry)               refeeItr.next();
+               m            = (HeapRegionNode)          me.getKey();
+               f            = (ReferenceEdgeProperties) me.getValue();
+
+               ChangeTupleSet changesToPass = new ChangeTupleSet().makeCanonical();
+
+               Iterator itrCprime = C.iterator();
+               while( itrCprime.hasNext() ) {
+                   ChangeTuple c = (ChangeTuple) itrCprime.next();
+                   if( f.getBeta().contains( c.getSetToMatch() ) ) {
+                       changesToPass = changesToPass.union( c );
+                   }
+               }
+
+               if( !changesToPass.isEmpty() ) {
+                   if( !nodePlannedChanges.containsKey( m ) ) {
+                       nodePlannedChanges.put( m, new ChangeTupleSet().makeCanonical() );
+                   }
+
+                   ChangeTupleSet currentChanges = nodePlannedChanges.get( m );
+
+                   if( !changesToPass.isSubset( currentChanges ) ) {
+
+                       nodePlannedChanges.put( m, currentChanges.union( changesToPass ) );
+                       todoNodes.add( m );
+                   }
+               }
+           }
+
+           todoNodes.remove( n );
+       }
+
+       propagateTokensOverEdges( todoEdges, edgePlannedChanges, nodesWithNewAlpha, edgesWithNewBeta );
+    }
+
+
+    protected void propagateTokensOverEdges( 
+        HashSet<ReferenceEdgeProperties>                   todoEdges,
+        Hashtable<ReferenceEdgeProperties, ChangeTupleSet> edgePlannedChanges,
+        HashSet<HeapRegionNode>                            nodesWithNewAlpha,
+        HashSet<ReferenceEdgeProperties>                   edgesWithNewBeta ) {
+       
+
+       while( !todoEdges.isEmpty() ) {
+           ReferenceEdgeProperties e = todoEdges.iterator().next();
+           todoEdges.remove( e );
+
+           if( !edgePlannedChanges.containsKey( e ) ) {
+               edgePlannedChanges.put( e, new ChangeTupleSet().makeCanonical() );
+           }
+           
+           ChangeTupleSet C = edgePlannedChanges.get( e );
+
+           ChangeTupleSet changesToPass = new ChangeTupleSet().makeCanonical();
+
+           Iterator itrC = C.iterator();
+           while( itrC.hasNext() ) {
+               ChangeTuple c = (ChangeTuple) itrC.next();
+               if( e.getBeta().contains( c.getSetToMatch() ) ) {
+                   ReachabilitySet withChange = e.getBeta().union( c.getSetToAdd() );
+                   e.setBetaNew( e.getBetaNew().union( withChange ) );
+                   edgesWithNewBeta.add( e );
+                   changesToPass = changesToPass.union( c );
+               }
+           }
+
+           OwnershipNode onSrc = e.getSrc();
+
+           if( !changesToPass.isEmpty() && onSrc instanceof HeapRegionNode ) {         
+               HeapRegionNode n = (HeapRegionNode) onSrc;
+               Iterator referItr = n.iteratorToReferencers();
+
+               while( referItr.hasNext() ) {
+                   OwnershipNode onRef = (OwnershipNode) referItr.next();
+                   ReferenceEdgeProperties f = onRef.getReferenceTo( n );
+                   
+                   if( !edgePlannedChanges.containsKey( f ) ) {
+                       edgePlannedChanges.put( f, new ChangeTupleSet().makeCanonical() );
+                   }
+                 
+                   ChangeTupleSet currentChanges = edgePlannedChanges.get( f );
+               
+                   if( !changesToPass.isSubset( currentChanges ) ) {
+                       todoEdges.add( f );
+                       edgePlannedChanges.put( f, currentChanges.union( changesToPass ) );
+                   }
+               }
+           }       
+       }       
     }
 
 
@@ -220,9 +360,10 @@ public class OwnershipGraph {
                ReferenceEdgeProperties rep2 = (ReferenceEdgeProperties) meH.getValue();
                ReachabilitySet beta2        = rep2.getBeta();
 
-               ReferenceEdgeProperties rep = rep2.copy();
-               rep.setIsInitialParamReflexive( false );
-               rep.setBeta( beta1.intersection( beta2 ) );
+               ReferenceEdgeProperties rep = 
+                   new ReferenceEdgeProperties( false,
+                                                false,
+                                                beta1.intersection( beta2 ) );
 
                addReferenceEdge( dstln, hrnOneHop, rep );
            }
@@ -259,15 +400,47 @@ public class OwnershipGraph {
                Map.Entry meS = (Map.Entry)               srcRegionsItr.next();
                hrnSrc        = (HeapRegionNode)          meS.getKey();
                repSrc        = (ReferenceEdgeProperties) meS.getValue();
+               
+               ReachabilitySet O = srcln.getReferenceTo( hrnSrc ).getBeta();
+
+
+               // propagate tokens over nodes starting from hrnSrc, and it will
+               // take care of propagating back up edges from any touched nodes
+               ChangeTupleSet Cy = O.unionUpArityToChangeSet( R );
+               propagateTokensOverNodes( hrnSrc, Cy, nodesWithNewAlpha, edgesWithNewBeta );
+
+
+               // then propagate back just up the edges from hrn
+               ChangeTupleSet Cx = R.unionUpArityToChangeSet( O );
+
+               HashSet<ReferenceEdgeProperties> todoEdges = 
+                   new HashSet<ReferenceEdgeProperties>();
+
+               Hashtable<ReferenceEdgeProperties, ChangeTupleSet> edgePlannedChanges =
+                   new Hashtable<ReferenceEdgeProperties, ChangeTupleSet>();
+
+               Iterator referItr = hrn.iteratorToReferencers();
+               while( referItr.hasNext() ) {
+                   OwnershipNode onRef = (OwnershipNode) referItr.next();
+                   ReferenceEdgeProperties repUpstream = onRef.getReferenceTo( hrn );
+
+                   todoEdges.add( repUpstream );
+                   edgePlannedChanges.put( repUpstream, Cx );
+               }
 
+               propagateTokensOverEdges( todoEdges, 
+                                         edgePlannedChanges,
+                                         nodesWithNewAlpha,
+                                         edgesWithNewBeta );
+
+               // finally, create the actual reference edge hrn->hrnSrc
                ReferenceEdgeProperties repNew 
-                   = new ReferenceEdgeProperties( false, false, null );
+                   = new ReferenceEdgeProperties( false, 
+                                                  false, 
+                                                  repSrc.getBetaNew().pruneBy( hrn.getAlpha() )
+                                                );
 
                addReferenceEdge( hrn, hrnSrc, repNew );
-               
-               ReachabilitySet O = srcln.getReferenceTo( hrnSrc ).getBeta();
-               ChangeTupleSet  C = O.unionUpArity( R );
-               propagateTokens( hrnSrc, C );
            }
        }       
 
@@ -338,7 +511,8 @@ public class OwnershipGraph {
        LabelNode dst = getLabelNodeFromTemp( td );
        
        clearReferenceEdgesFrom( dst );
-       addReferenceEdge( dst, hrnNewest, new ReferenceEdgeProperties( false ) );
+       
+       addReferenceEdge( dst, hrnNewest, new ReferenceEdgeProperties( false, false, hrnNewest.getAlpha() ) );
     }
 
 
@@ -363,41 +537,103 @@ public class OwnershipGraph {
        // nothing if the site is already in the list
        allocationSites.add( as );
 
+       // get the summary node for the allocation site in the context
+       // of this particular ownership graph
+       HeapRegionNode hrnSummary = getSummaryNode( as );
+
+       // merge oldest node into summary
+       Integer        idK  = as.getOldest();
+       HeapRegionNode hrnK = id2hrn.get( idK );
+       mergeIntoSummary( hrnK, hrnSummary );
+       
+       // move down the line of heap region nodes
+       // clobbering the ith and transferring all references
+       // to and from i-1 to node i.  Note that this clobbers
+       // the oldest node (hrnK) that was just merged into
+       // the summary
+       for( int i = allocationDepth - 1; i > 0; --i ) {            
+
+           // move references from the i-1 oldest to the ith oldest
+           Integer        idIth     = as.getIthOldest( i );
+           HeapRegionNode hrnI      = id2hrn.get( idIth );
+           Integer        idImin1th = as.getIthOldest( i - 1 );
+           HeapRegionNode hrnImin1  = id2hrn.get( idImin1th );
+
+           transferOnto( hrnImin1, hrnI );
+       }
+
+       // as stated above, the newest node should have had its
+       // references moved over to the second oldest, so we wipe newest
+       // in preparation for being the new object to assign something to
+       Integer        id0th = as.getIthOldest( 0 );
+       HeapRegionNode hrn0  = id2hrn.get( id0th );
+       assert hrn0 != null;
+
+       // clear all references in and out of newest node
+       clearReferenceEdgesFrom( hrn0 );
+       clearReferenceEdgesTo  ( hrn0 );
+       
+
+       // now tokens in reachability sets need to "age" also
+       ReferenceEdgeProperties repToAge = null;
+       Iterator itrAllLabelNodes = td2ln.entrySet().iterator();
+       while( itrAllLabelNodes.hasNext() ) {
+           Map.Entry me = (Map.Entry) itrAllLabelNodes.next();
+           LabelNode ln = (LabelNode) me.getValue();
+
+           Iterator itrEdges = ln.setIteratorToReferencedRegions();
+           while( itrEdges.hasNext() ) {
+               Map.Entry meE = (Map.Entry)               itrEdges.next();
+               repToAge      = (ReferenceEdgeProperties) meE.getValue();
+
+               ageTokens( as, repToAge );
+           }
+       }
+       HeapRegionNode hrnToAge = null;
+       Iterator itrAllHRNodes = id2hrn.entrySet().iterator();
+       while( itrAllHRNodes.hasNext() ) {
+           Map.Entry me = (Map.Entry)               itrAllHRNodes.next();
+           hrnToAge     = (HeapRegionNode)          me.getValue();
+
+           ageTokens( as, hrnToAge );
+
+           Iterator itrEdges = hrnToAge.setIteratorToReferencedRegions();
+           while( itrEdges.hasNext() ) {
+               Map.Entry meE = (Map.Entry)               itrEdges.next();
+               repToAge      = (ReferenceEdgeProperties) meE.getValue();
+
+               ageTokens( as, repToAge );
+           }
+       }
+
+
+       // after tokens have been aged, reset newest node's reachability
+       hrn0.setAlpha( new ReachabilitySet( 
+                          new TokenTupleSet( 
+                              new TokenTuple( hrn0 ) 
+                                           ) 
+                                         ).makeCanonical() 
+                      );
+    }
+
 
-       //////////////////////////////////////////////////////////////////
-       //
-       //  move existing references down the line toward
-       //  the oldest element, starting with the oldest
-       // 
-       //  An illustration:
-       //    TempDescriptor = the td passed into this function, left side of new statement
-       //    AllocationSite = { alpha0, alpha1, alpha2, alphaSummary }
-       //
-       //  1. Specially merge refs in/out at alpha2 into alphaSummary
-       //  2. Move refs in/out at alpha1 over to alpha2 (alpha1 becomes alpha2)
-       //  3. Move refs in/out at alpha0 over to alpha1
-       //  4. Assign reference from td to alpha0, which now represents a freshly allocated object
-       //
-       //////////////////////////////////////////////////////////////////
-
-
-       // first specially merge the references from the oldest
-       // node into the summary node, keeping track of 1-to-1 edges
+    protected HeapRegionNode getSummaryNode( AllocationSite as ) {
+       
        Integer        idSummary  = as.getSummary();
        HeapRegionNode hrnSummary = id2hrn.get( idSummary );
-       
-       // if this is null then we haven't touched this allocation site
-       // in the context of the current ownership graph, so simply
-       // allocate an appropriate heap region node
-       // this should only happen once per ownership per allocation site,
+
+       // If this is null then we haven't touched this allocation site
+       // in the context of the current ownership graph, so allocate
+       // heap region nodes appropriate for the entire allocation site.
+       // This should only happen once per ownership graph per allocation site,
        // and a particular integer id can be used to locate the heap region
        // in different ownership graphs that represents the same part of an
-       // allocation site
+       // allocation site.
        if( hrnSummary == null ) {
 
            boolean hasFlags = false;
            if( as.getType().isClass() ) {
-               hasFlags =  as.getType().getClassDesc().hasFlags();
+               hasFlags = as.getType().getClassDesc().hasFlags();
            }
 
            hrnSummary = createNewHeapRegionNode( idSummary,
@@ -423,104 +659,148 @@ public class OwnershipGraph {
            }
        }
 
-       // first transfer the references out of alpha_k to alpha_s
-       Integer        idK  = as.getOldest();
-       HeapRegionNode hrnK = id2hrn.get( idK );
+       return hrnSummary;
+    }
+
+
+    protected HeapRegionNode getShadowSummaryNode( AllocationSite as ) {
+       
+       Integer        idShadowSummary  = -(as.getSummary());
+       HeapRegionNode hrnShadowSummary = id2hrn.get( idShadowSummary );
+
+       if( hrnShadowSummary == null ) {
+
+           boolean hasFlags = false;
+           if( as.getType().isClass() ) {
+               hasFlags = as.getType().getClassDesc().hasFlags();
+           }
 
+           hrnShadowSummary = createNewHeapRegionNode( idShadowSummary,
+                                                       false,
+                                                       hasFlags,
+                                                       true,
+                                                       false,
+                                                       as,
+                                                       null,
+                                                       as + "\\n" + as.getType() + "\\nshadowSum" );
+
+           for( int i = 0; i < as.getAllocationDepth(); ++i ) {
+               Integer idShadowIth = -(as.getIthOldest( i ));
+               assert !id2hrn.containsKey( idShadowIth );
+               createNewHeapRegionNode( idShadowIth,
+                                        true,
+                                        hasFlags,
+                                        false,
+                                        false,
+                                        as,
+                                        null,
+                                        as + "\\n" + as.getType() + "\\n" + i + " shadow" );
+           }
+       }
+
+       return hrnShadowSummary;
+    }
+
+
+    protected void mergeIntoSummary( HeapRegionNode hrn, HeapRegionNode hrnSummary ) {
+       assert hrnSummary.isNewSummary();
+
+       // transfer references _from_ hrn over to hrnSummary
        HeapRegionNode hrnReferencee = null;
-       Iterator       itrReferencee = hrnK.setIteratorToReferencedRegions();
+       Iterator       itrReferencee = hrn.setIteratorToReferencedRegions();
        while( itrReferencee.hasNext() ) {
            Map.Entry               me  = (Map.Entry)               itrReferencee.next();
            hrnReferencee               = (HeapRegionNode)          me.getKey();
            ReferenceEdgeProperties rep = (ReferenceEdgeProperties) me.getValue();
-           
-           // determine if another summary node is already referencing this referencee
-           boolean       hasSummaryReferencer = false;
-           OwnershipNode onReferencer         = null;
-           Iterator      itrReferencer        = hrnReferencee.iteratorToReferencers();
-           while( itrReferencer.hasNext() ) {
-               onReferencer = (OwnershipNode) itrReferencer.next();
-               if( onReferencer instanceof HeapRegionNode ) {
-                   HeapRegionNode hrnPossibleSummary = (HeapRegionNode) onReferencer;
-                   if( hrnPossibleSummary.isNewSummary() ) {
-                       hasSummaryReferencer = true;
-                   }
-               }
+
+           ReferenceEdgeProperties repSummary = hrnSummary.getReferenceTo( hrnReferencee );
+           ReferenceEdgeProperties repMerged = rep.copy();
+
+           if( repSummary == null ) {      
+               // the merge is trivial, nothing to be done
+           } else {
+               // otherwise an edge from the referencer to hrnSummary exists already
+               // and the edge referencer->hrn should be merged with it
+               repMerged.setBeta( repMerged.getBeta().union( repSummary.getBeta() ) );
            }
 
-           addReferenceEdge( hrnSummary,
-                             hrnReferencee,
-                             new ReferenceEdgeProperties( !hasSummaryReferencer ) );
+           addReferenceEdge( hrnSummary, hrnReferencee, repMerged );
        }
 
-       // next transfer references to alpha_k over to alpha_s
+       // next transfer references _to_ hrn over to hrnSummary
        OwnershipNode onReferencer  = null;
-       Iterator      itrReferencer = hrnK.iteratorToReferencers();
+       Iterator      itrReferencer = hrn.iteratorToReferencers();
        while( itrReferencer.hasNext() ) {
            onReferencer = (OwnershipNode) itrReferencer.next();
            
-           ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrnK );
-           assert rep != null;
-           
-           addReferenceEdge( onReferencer, hrnSummary, rep.copy() );
-       }
+           ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrn );
+           assert rep != null;     
+           ReferenceEdgeProperties repSummary = onReferencer.getReferenceTo( hrnSummary );
+           ReferenceEdgeProperties repMerged = rep.copy();
 
-       
-       // then move down the line of heap region nodes
-       // clobbering the ith and transferring all references
-       // to and from i-1 to node i.  Note that this clobbers
-       // the oldest node (alpha_k) that was just merged into
-       // the summary above and should move everything from
-       // alpha_0 to alpha_1 before we finish
-       for( int i = allocationDepth - 1; i > 0; --i ) {            
+           if( repSummary == null ) {      
+               // the merge is trivial, nothing to be done
+           } else {
+               // otherwise an edge from the referencer to alpha_S exists already
+               // and the edge referencer->alpha_K should be merged with it
+               repMerged.setBeta( repMerged.getBeta().union( repSummary.getBeta() ) );
+           }
 
-           // move references from the i-1 oldest to the ith oldest
-           Integer        idIth     = as.getIthOldest( i );
-           HeapRegionNode hrnI      = id2hrn.get( idIth );
-           Integer        idImin1th = as.getIthOldest( i - 1 );
-           HeapRegionNode hrnImin1  = id2hrn.get( idImin1th );
+           addReferenceEdge( onReferencer, hrnSummary, repMerged );
+       }
 
-           // clear references in and out of node i
-           clearReferenceEdgesFrom( hrnI );
-           clearReferenceEdgesTo  ( hrnI );
-
-           // copy each edge in and out of i-1 to i        
-           hrnReferencee = null;
-           itrReferencee = hrnImin1.setIteratorToReferencedRegions();
-           while( itrReferencee.hasNext() ) {
-               Map.Entry               me  = (Map.Entry)               itrReferencee.next();
-               hrnReferencee               = (HeapRegionNode)          me.getKey();
-               ReferenceEdgeProperties rep = (ReferenceEdgeProperties) me.getValue();
-               
-               addReferenceEdge( hrnI, hrnReferencee, rep.copy() );
-           }
+       // then merge hrn reachability into hrnSummary
+       hrnSummary.setAlpha( hrnSummary.getAlpha().union( hrn.getAlpha() ) );
+    }
 
-           onReferencer  = null;
-           itrReferencer = hrnImin1.iteratorToReferencers();
-           while( itrReferencer.hasNext() ) {
-               onReferencer = (OwnershipNode) itrReferencer.next();
 
-               ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrnImin1 );
-               assert rep != null;
+    protected void transferOnto( HeapRegionNode hrnA, HeapRegionNode hrnB ) {
 
-               addReferenceEdge( onReferencer, hrnI, rep.copy() );
-           }       
+       // clear references in and out of node i
+       clearReferenceEdgesFrom( hrnB );
+       clearReferenceEdgesTo  ( hrnB );
+       
+       // copy each edge in and out of A to B
+       HeapRegionNode hrnReferencee = null;
+       Iterator       itrReferencee = hrnA.setIteratorToReferencedRegions();
+       while( itrReferencee.hasNext() ) {
+           Map.Entry               me  = (Map.Entry)               itrReferencee.next();
+           hrnReferencee               = (HeapRegionNode)          me.getKey();
+           ReferenceEdgeProperties rep = (ReferenceEdgeProperties) me.getValue();
+           
+           addReferenceEdge( hrnB, hrnReferencee, rep.copy() );
        }
+       
+       OwnershipNode onReferencer  = null;
+       Iterator      itrReferencer = hrnA.iteratorToReferencers();
+       while( itrReferencer.hasNext() ) {
+           onReferencer = (OwnershipNode) itrReferencer.next();
+           
+           ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrnA );
+           assert rep != null;
+           
+           addReferenceEdge( onReferencer, hrnB, rep.copy() );
+       }           
+       
+       // replace hrnB reachability with hrnA's
+       hrnB.setAlpha( hrnA.getAlpha() );
+    }
 
-       // as stated above, the newest node alpha_0 should have had its
-       // references moved over to alpha_1, so we can wipe alpha_0 clean
-       // in preparation for operations that want to reference a freshly
-       // allocated object from this allocation site
-       Integer        id0th = as.getIthOldest( 0 );
-       HeapRegionNode hrn0  = id2hrn.get( id0th );
 
-       // the loop to move references from i-1 to i should
-       // have touched this node, therefore assert it is non-null
-       assert hrn0 != null;
+    protected void ageTokens( AllocationSite as, ReferenceEdgeProperties rep ) {
+       rep.setBeta( rep.getBeta().ageTokens( as ) );
+    }
 
-       // clear all references in and out of newest node
-       clearReferenceEdgesFrom( hrn0 );
-       clearReferenceEdgesTo  ( hrn0 );
+    protected void ageTokens( AllocationSite as, HeapRegionNode hrn ) {
+       hrn.setAlpha( hrn.getAlpha().ageTokens( as ) );
+    }
+
+    protected void majorAgeTokens( AllocationSite as, ReferenceEdgeProperties rep ) {
+       //rep.setBeta( rep.getBeta().majorAgeTokens( as ) );
+    }
+
+    protected void majorAgeTokens( AllocationSite as, HeapRegionNode hrn ) {
+       //hrn.setAlpha( hrn.getAlpha().majorAgeTokens( as ) );
     }
 
     
@@ -539,17 +819,21 @@ public class OwnershipGraph {
     public void resolveMethodCall( FlatCall                fc,
                                   boolean                 isStatic,
                                   FlatMethod              fm,
-                                  OwnershipGraph          ogCallee ) { //,
-       //HashSet<AllocationSite> allocSiteSet ) {
-       
-       // first age all of the allocation sites from
-       // the callee graph in this graph
-       Iterator i = ogCallee.allocationSites.iterator();
+                                  OwnershipGraph          ogCallee ) {
+
+       // verify the existence of allocation sites and their
+       // shadows from the callee in the context of this caller graph
+       Iterator<AllocationSite> i = ogCallee.allocationSites.iterator();
        while( i.hasNext() ) {
-           AllocationSite allocSite = (AllocationSite) i.next();           
-           this.age( allocSite );
+           AllocationSite allocSite = i.next();    
+           HeapRegionNode hrnSummary       = getSummaryNode      ( allocSite );
+           HeapRegionNode hrnShadowSummary = getShadowSummaryNode( allocSite );
        }
 
+
+       
+       /*
+
        // in non-static methods there is a "this" pointer
        // that should be taken into account
        if( isStatic ) {
@@ -605,9 +889,9 @@ public class OwnershipGraph {
                        //System.out.println( "idCallee is "+idCallee );
                        //System.out.println( "idChildCallee is "+idChildCallee );
                        
-                       try {
-                           writeGraph( "caller", false, false );
-                           ogCallee.writeGraph( "callee", false, false );
+                       try {                       
+                           writeGraph( "caller", false, false, false );
+                           ogCallee.writeGraph( "callee", false, false, false );                           
                        } catch( IOException e ) {}
                    }
 
@@ -638,6 +922,7 @@ public class OwnershipGraph {
                }
            } 
        }       
+       */
     }
 
     private HashSet<HeapRegionNode> getHRNSetThatPossiblyMapToCalleeHRN( OwnershipGraph ogCallee,
@@ -1294,6 +1579,24 @@ public class OwnershipGraph {
 
 
     // for writing ownership graphs to dot files
+    public void writeGraph( Descriptor methodDesc,
+                           FlatNode   fn,
+                           boolean    writeLabels,
+                           boolean    labelSelect,
+                           boolean    pruneGarbage,
+                           boolean    writeReferencers 
+                           ) throws java.io.IOException {
+       writeGraph(
+                  methodDesc.getSymbol() +
+                  methodDesc.getNum() +
+                  fn.toString(),
+                  writeLabels,
+                  labelSelect,
+                  pruneGarbage,
+                  writeReferencers
+                  );
+    }
+
     public void writeGraph( Descriptor methodDesc,
                            FlatNode   fn,
                            boolean    writeLabels,
@@ -1304,6 +1607,8 @@ public class OwnershipGraph {
                   methodDesc.getNum() +
                   fn.toString(),
                   writeLabels,
+                  false,
+                  false,
                   writeReferencers
                   );
     }
@@ -1317,12 +1622,33 @@ public class OwnershipGraph {
                   methodDesc.getNum() +
                   "COMPLETE",
                   writeLabels,
+                  false,
+                  false,
+                  writeReferencers
+                   );
+    }
+
+    public void writeGraph( Descriptor methodDesc,
+                           boolean    writeLabels,
+                           boolean    labelSelect,
+                           boolean    pruneGarbage,
+                           boolean    writeReferencers 
+                           ) throws java.io.IOException {
+       writeGraph( 
+                  methodDesc.getSymbol() +
+                  methodDesc.getNum() +
+                  "COMPLETE",
+                  writeLabels,
+                  labelSelect,
+                  pruneGarbage,
                   writeReferencers
                    );
     }
 
     public void writeGraph( String graphName,
                            boolean writeLabels,
+                           boolean labelSelect,
+                           boolean pruneGarbage,
                            boolean writeReferencers 
                            ) throws java.io.IOException {
 
@@ -1334,22 +1660,23 @@ public class OwnershipGraph {
        bw.write( "digraph "+graphName+" {\n" );
        //bw.write( "  size=\"7.5,10\";\n" );
 
-
-       // then visit every heap region node
        HashSet<HeapRegionNode> visited = new HashSet<HeapRegionNode>();
 
-       Set      s = id2hrn.entrySet();
-       Iterator i = s.iterator();
-       while( i.hasNext() ) {
-           Map.Entry      me  = (Map.Entry)      i.next();
-           HeapRegionNode hrn = (HeapRegionNode) me.getValue();
-           if( !visited.contains( hrn ) ) {
-               traverseHeapRegionNodes( VISIT_HRN_WRITE_FULL, 
-                                        hrn, 
-                                        bw, 
-                                        null, 
-                                        visited, 
-                                        writeReferencers );
+       // then visit every heap region node
+       if( !pruneGarbage ) {       
+           Set      s = id2hrn.entrySet();
+           Iterator i = s.iterator();
+           while( i.hasNext() ) {
+               Map.Entry      me  = (Map.Entry)      i.next();
+               HeapRegionNode hrn = (HeapRegionNode) me.getValue();
+               if( !visited.contains( hrn ) ) {
+                   traverseHeapRegionNodes( VISIT_HRN_WRITE_FULL, 
+                                            hrn, 
+                                            bw, 
+                                            null, 
+                                            visited, 
+                                            writeReferencers );
+               }
            }
        }
 
@@ -1358,23 +1685,42 @@ public class OwnershipGraph {
 
        // then visit every label node, useful for debugging
        if( writeLabels ) {
-           s = td2ln.entrySet();
-           i = s.iterator();
+           Set      s = td2ln.entrySet();
+           Iterator i = s.iterator();
            while( i.hasNext() ) {
                Map.Entry me = (Map.Entry) i.next();
                LabelNode ln = (LabelNode) me.getValue();
                
+               if( labelSelect ) {
+                   String labelStr = ln.getTempDescriptorString();
+                   if( labelStr.startsWith( "___temp"      ) ||
+                       labelStr.startsWith( "___dst"       ) ||
+                       labelStr.startsWith( "___srctmp"   ) ||
+                       labelStr.startsWith( "___neverused" )   ) {
+                       continue;
+                   }
+               }
+
                HeapRegionNode hrn = null;
                Iterator heapRegionsItr = ln.setIteratorToReferencedRegions();
                while( heapRegionsItr.hasNext() ) {
                    Map.Entry meH               = (Map.Entry)               heapRegionsItr.next();
                    hrn                         = (HeapRegionNode)          meH.getKey();
                    ReferenceEdgeProperties rep = (ReferenceEdgeProperties) meH.getValue();
+
+                   if( pruneGarbage && !visited.contains( hrn ) ) {
+                       traverseHeapRegionNodes( VISIT_HRN_WRITE_FULL, 
+                                                hrn, 
+                                                bw, 
+                                                null, 
+                                                visited, 
+                                                writeReferencers );
+                   }
                    
                    bw.write( "  "        + ln.toString() +
                              " -> "      + hrn.toString() +
                              "[label=\"" + rep.toEdgeLabelString() +
-                             "\"];\n" );
+                             "\",decorate];\n" );
                }
            }
        }
@@ -1455,7 +1801,7 @@ public class OwnershipGraph {
                bw.write( "  "        + hrn.toString() +
                          " -> "      + hrnChild.toString() +
                          "[label=\"" + rep.toEdgeLabelString() +
-                         "\"];\n" );
+                         "\",decorate];\n" );
                break;
            }