From: jjenista Date: Tue, 5 Aug 2008 18:55:55 +0000 (+0000) Subject: Break aging into smaller procedures and improve graphing for method call work. X-Git-Tag: preEdgeChange~27 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8ba77f01d67c0ec1e6e2ac91f37518ca9ec90976;p=IRC.git Break aging into smaller procedures and improve graphing for method call work. --- diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java index a7dfd223..016929e8 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java @@ -280,7 +280,7 @@ public class OwnershipAnalysis { if( !og.equals( ogPrev ) ) { mapDescriptorToCompleteOwnershipGraph.put( d, og ); - og.writeGraph( d, true, true, false ); + og.writeGraph( d, true, true, true, false ); // only methods have dependents, tasks cannot // be invoked by any user program calls @@ -532,6 +532,9 @@ public class OwnershipAnalysis { } + // this method should generate integers strictly greater than zero! + // special "shadow" regions are made from a heap region by negating + // the ID static public Integer generateUniqueHeapRegionNodeID() { ++uniqueIDcount; return new Integer( uniqueIDcount ); diff --git a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java index ecb65e8e..65b39c93 100644 --- a/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java +++ b/Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java @@ -537,36 +537,98 @@ 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 ); - ////////////////////////////////////////////////////////////////// - // - // 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 + // 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() + ); + } + + + 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; @@ -597,12 +659,55 @@ 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(); @@ -614,21 +719,21 @@ public class OwnershipGraph { 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 + // 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, 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 ); + ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrn ); assert rep != null; ReferenceEdgeProperties repSummary = onReferencer.getReferenceTo( hrnSummary ); ReferenceEdgeProperties repMerged = rep.copy(); @@ -644,113 +749,44 @@ public class OwnershipGraph { addReferenceEdge( onReferencer, hrnSummary, repMerged ); } - // then merge alpha_k reachability into alpha_s - hrnSummary.setAlpha( hrnSummary.getAlpha().union( hrnK.getAlpha() ) ); - - - // 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 ) { - - // 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 ); - - // 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() ); - } - - onReferencer = null; - itrReferencer = hrnImin1.iteratorToReferencers(); - while( itrReferencer.hasNext() ) { - onReferencer = (OwnershipNode) itrReferencer.next(); - - ReferenceEdgeProperties rep = onReferencer.getReferenceTo( hrnImin1 ); - assert rep != null; - - addReferenceEdge( onReferencer, hrnI, rep.copy() ); - } - - // replace hrnI reachability with hrnImin1 - hrnI.setAlpha( hrnImin1.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 ); + // then merge hrn reachability into hrnSummary + hrnSummary.setAlpha( hrnSummary.getAlpha().union( hrn.getAlpha() ) ); + } - // 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 transferOnto( HeapRegionNode hrnA, HeapRegionNode hrnB ) { - // clear all references in and out of newest node - clearReferenceEdgesFrom( hrn0 ); - clearReferenceEdgesTo ( hrn0 ); + // clear references in and out of node i + clearReferenceEdgesFrom( hrnB ); + clearReferenceEdgesTo ( hrnB ); - - // now tokens in reachability sets need to "age" as well - 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 ); - } + // 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() ); } - - - // after tokens have been aged, reset newest node's reachability - hrn0.setAlpha( new ReachabilitySet( - new TokenTupleSet( - new TokenTuple( hrn0 ) - ) - ).makeCanonical() - ); + + 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() ); } + protected void ageTokens( AllocationSite as, ReferenceEdgeProperties rep ) { rep.setBeta( rep.getBeta().ageTokens( as ) ); } @@ -759,6 +795,14 @@ public class OwnershipGraph { 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 ) ); + } + // some notes: // the heap regions that are specially allocated as multiple-object @@ -775,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 ) { @@ -874,6 +922,7 @@ public class OwnershipGraph { } } } + */ } private HashSet getHRNSetThatPossiblyMapToCalleeHRN( OwnershipGraph ogCallee, @@ -1534,6 +1583,7 @@ public class OwnershipGraph { FlatNode fn, boolean writeLabels, boolean labelSelect, + boolean pruneGarbage, boolean writeReferencers ) throws java.io.IOException { writeGraph( @@ -1542,6 +1592,7 @@ public class OwnershipGraph { fn.toString(), writeLabels, labelSelect, + pruneGarbage, writeReferencers ); } @@ -1557,6 +1608,7 @@ public class OwnershipGraph { fn.toString(), writeLabels, false, + false, writeReferencers ); } @@ -1571,6 +1623,7 @@ public class OwnershipGraph { "COMPLETE", writeLabels, false, + false, writeReferencers ); } @@ -1578,6 +1631,7 @@ public class OwnershipGraph { public void writeGraph( Descriptor methodDesc, boolean writeLabels, boolean labelSelect, + boolean pruneGarbage, boolean writeReferencers ) throws java.io.IOException { writeGraph( @@ -1586,6 +1640,7 @@ public class OwnershipGraph { "COMPLETE", writeLabels, labelSelect, + pruneGarbage, writeReferencers ); } @@ -1593,6 +1648,7 @@ public class OwnershipGraph { public void writeGraph( String graphName, boolean writeLabels, boolean labelSelect, + boolean pruneGarbage, boolean writeReferencers ) throws java.io.IOException { @@ -1604,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 ); + } } } @@ -1628,8 +1685,8 @@ 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(); @@ -1650,6 +1707,15 @@ public class OwnershipGraph { 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() + diff --git a/Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java b/Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java index e72c5f10..a203ca46 100644 --- a/Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java +++ b/Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java @@ -45,6 +45,17 @@ public class Foo { public void ruinSomeFoos( Foo a, Foo b ) { a.x = b.x; } + + public void test( Foo p0, Foo p1 ) { + Foo f0 = new Foo(); + Foo f1 = new Foo(); + Foo f2 = new Foo(); + + f0.x = f1; + p0.x = f0; + p1.x = f1; + p1.x = f2; + } } @@ -54,7 +65,7 @@ public class Foo { // a heap region that is multi-object, flagged, not summary task Startup( StartupObject s{ initialstate } ) { - + /* while( false ) { Foo a = new Foo(); a.x = new Foo(); @@ -98,7 +109,21 @@ task Startup( StartupObject s{ initialstate } ) { c.x = b; b = c; } + */ + + Foo aa = new Foo(); + aa.test( aa, aa ); + /* + Foo ab = new Foo(); + Foo ac = new Foo(); + Foo ad = new Foo(); + + aa.x = ab; + ab.x = ac; + ab.x = aa; + ad.x = aa; + */ taskexit( s{ !initialstate } ); }