assert rep != null;
referencer.addReferencedRegion( referencee, rep );
referencee.addReferencer( referencer );
+ rep.setSrc( referencer );
+ rep.setDst( referencee );
}
protected void removeReferenceEdge( OwnershipNode referencer,
}
+ 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 ) );
+ }
+ }
+ }
+ }
}
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 );
}
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 );
}
}
LabelNode dst = getLabelNodeFromTemp( td );
clearReferenceEdgesFrom( dst );
- addReferenceEdge( dst, hrnNewest, new ReferenceEdgeProperties( false ) );
+
+ addReferenceEdge( dst, hrnNewest, new ReferenceEdgeProperties( false, false, hrnNewest.getAlpha() ) );
}
// 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,
}
}
- // 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 ) );
}
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 ) {
//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 ) {}
}
}
}
}
+ */
}
private HashSet<HeapRegionNode> getHRNSetThatPossiblyMapToCalleeHRN( OwnershipGraph ogCallee,
// 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,
methodDesc.getNum() +
fn.toString(),
writeLabels,
+ false,
+ false,
writeReferencers
);
}
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 {
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 );
+ }
}
}
// 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" );
}
}
}
bw.write( " " + hrn.toString() +
" -> " + hrnChild.toString() +
"[label=\"" + rep.toEdgeLabelString() +
- "\"];\n" );
+ "\",decorate];\n" );
break;
}