Stable capture.
authorjjenista <jjenista>
Thu, 27 Mar 2008 21:31:29 +0000 (21:31 +0000)
committerjjenista <jjenista>
Thu, 27 Mar 2008 21:31:29 +0000 (21:31 +0000)
Method call resolution algorithm is drafted, but clearly there are bugs
because a simple program with an alias-creating method doesn't reflect
the correct heap structure in the caller graph.

Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java
Robust/src/Analysis/OwnershipAnalysis/ReferenceEdgeProperties.java
Robust/src/Tests/OwnershipAnalysisTest/test01/test01.java

index 5753eb53bdbd70d8c011e76e014bb2a18f195a81..1bc279c73ccd628731f54a88c9a3619c34139c79 100644 (file)
@@ -524,67 +524,97 @@ public class OwnershipGraph {
                    // So now make a set of possible source heaps in the caller graph
                    // and a set of destination heaps in the caller graph, and make
                    // a reference edge in the caller for every possible (src,dst) pair 
-                   HashSet<HeapRegionNode> possibleCallerSrcs = new HashSet<HeapRegionNode>();
-                   HashSet<HeapRegionNode> possibleCallerDsts = new HashSet<HeapRegionNode>();       
-                   
-                   // first figure out the set of possible sources in the caller
-                   if( ogCallee.id2paramIndex.containsKey( idCallee ) ) {
-                       // the heap region that is the source of this
-                       // reference edge won't have a matching ID in the
-                       // caller graph because it is specifically allocated
-                       // for a particular parameter.  Use that information
-                       // to find the corresponding argument label in the
-                       // caller in order to create the proper reference edge
-                       // or edges.
-                       assert !id2hrn.containsKey( idCallee );
-                       
-                       Integer paramIndex = ogCallee.id2paramIndex.get( idCallee );
-                       TempDescriptor argTemp;
-                       
-                       // now depending on whether the callee is static or not
-                       // we need to account for a "this" argument in order to
-                       // find the matching argument in the caller context
-                       if( isStatic ) {
-                           argTemp = fc.getArg( paramIndex );
-                       } else {
-                           if( paramIndex == 0 ) {
-                               argTemp = fc.getThis();
-                           } else {
-                               argTemp = fc.getArg( paramIndex - 1 );
-                           }
+                   HashSet<HeapRegionNode> possibleCallerSrcs =  
+                       getHRNSetThatPossiblyMapToCalleeHRN( ogCallee,
+                                                            idCallee,
+                                                            fc,
+                                                            isStatic );
+
+                   HashSet<HeapRegionNode> possibleCallerDsts = 
+                       getHRNSetThatPossiblyMapToCalleeHRN( ogCallee,
+                                                            idChildCallee,
+                                                            fc,
+                                                            isStatic );
+
+                   // make every possible pair of {srcSet} -> {dstSet} edges in the caller
+                   Iterator srcItr = possibleCallerSrcs.iterator();
+                   while( srcItr.hasNext() ) {
+                       HeapRegionNode src = (HeapRegionNode) srcItr.next();
+
+                       Iterator dstItr = possibleCallerDsts.iterator();
+                       while( dstItr.hasNext() ) {
+                           HeapRegionNode dst = (HeapRegionNode) dstItr.next();
+
+                           ReferenceEdgeProperties rep = new ReferenceEdgeProperties();
+                           addReferenceEdge( src, dst, rep );
                        }
-                       
-                       LabelNode argLabel = getLabelNodeFromTemp( argTemp );
-                       Iterator argHeapRegionsItr = argLabel.setIteratorToReferencedRegions();
-                       while( argHeapRegionsItr.hasNext() ) {
-                           Map.Entry meArg                = (Map.Entry)               argHeapRegionsItr.next();
-                           HeapRegionNode argHeapRegion   = (HeapRegionNode)          meArg.getKey();
-                           ReferenceEdgeProperties repArg = (ReferenceEdgeProperties) meArg.getValue();
-                           
-                           possibleCallerSrcs.add( (HeapRegionNode) argHeapRegion );
-                       }
-                       
-                   } else {
-                       // this heap region is not a parameter, so it should
-                       // have a matching heap region in the caller graph
-                       
-                       /*
-                         try {
-                         ogCallee.writeGraph( "TheCallee" );
-                         writeGraph( "TheCaller" );
-                         } catch( Exception e ) {}
-                       */
-                       
-                       assert id2hrn.containsKey( idCallee );
-                       possibleCallerSrcs.add( id2hrn.get( idCallee ) );
                    }
-
-                   // second find the set of possible destinations in the caller
                }
            } 
        }       
     }
 
+    private HashSet<HeapRegionNode> getHRNSetThatPossiblyMapToCalleeHRN( OwnershipGraph ogCallee,
+                                                                        Integer        idCallee,
+                                                                        FlatCall       fc,
+                                                                        boolean        isStatic ) {
+
+       HashSet<HeapRegionNode> possibleCallerHRNs = new HashSet<HeapRegionNode>();
+
+       if( ogCallee.id2paramIndex.containsKey( idCallee ) ) {
+           // the heap region that is part of this
+           // reference edge won't have a matching ID in the
+           // caller graph because it is specifically allocated
+           // for a particular parameter.  Use that information
+           // to find the corresponding argument label in the
+           // caller in order to create the proper reference edge
+           // or edges.
+           assert !id2hrn.containsKey( idCallee );
+           
+           Integer paramIndex = ogCallee.id2paramIndex.get( idCallee );
+           TempDescriptor argTemp;
+           
+           // now depending on whether the callee is static or not
+           // we need to account for a "this" argument in order to
+           // find the matching argument in the caller context
+           if( isStatic ) {
+               argTemp = fc.getArg( paramIndex );
+           } else {
+               if( paramIndex == 0 ) {
+                   argTemp = fc.getThis();
+               } else {
+                   argTemp = fc.getArg( paramIndex - 1 );
+               }
+           }
+           
+           LabelNode argLabel = getLabelNodeFromTemp( argTemp );
+           Iterator argHeapRegionsItr = argLabel.setIteratorToReferencedRegions();
+           while( argHeapRegionsItr.hasNext() ) {
+               Map.Entry meArg                = (Map.Entry)               argHeapRegionsItr.next();
+               HeapRegionNode argHeapRegion   = (HeapRegionNode)          meArg.getKey();
+               ReferenceEdgeProperties repArg = (ReferenceEdgeProperties) meArg.getValue();
+               
+               possibleCallerHRNs.add( (HeapRegionNode) argHeapRegion );
+           }
+           
+       } else {
+           // this heap region is not a parameter, so it should
+           // have a matching heap region in the caller graph
+           
+           /*
+             try {
+             ogCallee.writeGraph( "TheCallee" );
+             writeGraph( "TheCaller" );
+             } catch( Exception e ) {}
+           */
+           
+           assert id2hrn.containsKey( idCallee );
+           possibleCallerHRNs.add( id2hrn.get( idCallee ) );
+       }
+
+       return possibleCallerHRNs;
+    }
+    
 
 
     ////////////////////////////////////////////////////
index bc62ed84ed957f5ed41e4c7419bf11d961d5a38a..eee529869093c4851310cf264e018a17aed51793 100644 (file)
@@ -2,6 +2,11 @@ package Analysis.OwnershipAnalysis;
 
 public class ReferenceEdgeProperties {
 
+    public ReferenceEdgeProperties() {
+       this.isUnique                = false;
+       this.isInitialParamReflexive = false;
+    }    
+
     public ReferenceEdgeProperties( boolean isUnique ) {
        this.isUnique                = isUnique;
        this.isInitialParamReflexive = false;
index 541f8dba3e53c6ed88943e484f8b91d552b735ac..483c3e31950b3e2d42f938319a096631af92e815 100644 (file)
@@ -20,6 +20,7 @@ public class Penguin {
 }
 */
 
+/*
 public class Voo {
     flag f; int x; Baw b;
 
@@ -33,13 +34,30 @@ public class Baw {
 
     public void doTheBaw( Voo v ) { v = new Voo(); }
 }
+*/
+
+public class Foo {
+    public Foo() {}
 
+    public Foo x;
+
+    public void ruinSomeFoos( Foo a, Foo b ) {
+       a.x = b.x;
+    }
+}
 
 // this empty task should still create a non-empty
 // ownership graph showing parameter allocation
 // look for the parameter s as a label referencing
 // a heap region that is multi-object, flagged, not summary
 task Startup( StartupObject s{ initialstate } ) {
+    Foo a = new Foo();
+    Foo b = new Foo();
+    Foo c = new Foo();
+    
+    c.ruinSomeFoos( a, b );
+
     taskexit( s{ !initialstate } );
 }
 
@@ -47,6 +65,7 @@ task Startup( StartupObject s{ initialstate } ) {
 // be a heap region for the parameter, and several
 // heap regions for the allocation site, but the label
 // merely points to the newest region
+/*
 task NewObject( Voo v{ f } ) {
     Voo w = new Voo();
     Baw b = new Baw();
@@ -80,3 +99,4 @@ task NewInLoop( Voo v{ f } ) {
 
     taskexit( v{ !f } );
 }
+*/