X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FOwnershipAnalysis%2FOwnershipGraph.java;h=65b39c9345c91df262cb3cbca310d8b2de4d7030;hb=8ba77f01d67c0ec1e6e2ac91f37518ca9ec90976;hp=cee91235777ddb6224dfbd490e1242106db11529;hpb=4720a1389e07ebc94012b458c93d4e349dff2f74;p=IRC.git diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java index cee91235..65b39c93 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java @@ -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 nodesWithNewAlpha, + HashSet edgesWithNewBeta ) { - protected void propagateTokens( HeapRegionNode nPrime, ChangeTupleSet c0 ) { + HashSet todoNodes + = new HashSet(); + todoNodes.add( nPrime ); + HashSet todoEdges + = new HashSet(); + + Hashtable nodePlannedChanges + = new Hashtable(); + nodePlannedChanges.put( nPrime, c0 ); + + Hashtable edgePlannedChanges + = new Hashtable(); + + + 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 todoEdges, + Hashtable edgePlannedChanges, + HashSet nodesWithNewAlpha, + HashSet 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 todoEdges = + new HashSet(); + + Hashtable edgePlannedChanges = + new Hashtable(); + + 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 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 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 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 visited = new HashSet(); - 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; }