getting close to effects for new disjoint analysis
[IRC.git] / Robust / src / Analysis / Disjoint / DisjointAnalysis.java
index cf02283affb8d8ed3080fe956a5f3634ade6fc3e..ee933a70238204f621364c4a8d618c6f5acdd586 100644 (file)
@@ -420,6 +420,11 @@ public class DisjointAnalysis {
   protected Hashtable< Descriptor, Set<Descriptor> >
     mapDescriptorToSetDependents;
 
+  // if the analysis client wants to flag allocation sites
+  // programmatically, it should provide a set of FlatNew
+  // statements--this may be null if unneeded
+  protected Set<FlatNew> sitesToFlag;
+
   // maps each flat new to one analysis abstraction
   // allocate site object, these exist outside reach graphs
   protected Hashtable<FlatNew, AllocSite>
@@ -559,10 +564,11 @@ public class DisjointAnalysis {
                           CallGraph        cg,
                           Liveness         l,
                           ArrayReferencees ar,
+                           Set<FlatNew> sitesToFlag,
                            RBlockRelationAnalysis rra,
                            RBlockStatusAnalysis rsa
                            ) {
-    init( s, tu, cg, l, ar, rra, rsa );
+    init( s, tu, cg, l, ar, sitesToFlag, rra, rsa );
   }
   
   protected void init( State            state,
@@ -570,19 +576,21 @@ public class DisjointAnalysis {
                        CallGraph        callGraph,
                        Liveness         liveness,
                        ArrayReferencees arrayReferencees,
+                       Set<FlatNew> sitesToFlag,
                        RBlockRelationAnalysis rra,
                        RBlockStatusAnalysis rsa
                        ) {
          
     analysisComplete = false;
     
-    this.state                   = state;
-    this.typeUtil                = typeUtil;
-    this.callGraph               = callGraph;
-    this.liveness                = liveness;
-    this.arrayReferencees        = arrayReferencees;
-    this.rblockRel               = rra;
-    this.rblockStatus         = rsa;
+    this.state            = state;
+    this.typeUtil         = typeUtil;
+    this.callGraph        = callGraph;
+    this.liveness         = liveness;
+    this.arrayReferencees = arrayReferencees;
+    this.sitesToFlag      = sitesToFlag;
+    this.rblockRel        = rra;
+    this.rblockStatus     = rsa;
 
     if( rblockRel != null ) {
       doEffectsAnalysis = true;
@@ -1289,6 +1297,11 @@ public class DisjointAnalysis {
     case FKind.FlatSESEEnterNode:
       sese = (FlatSESEEnterNode) fn;
 
+      if( sese.getIsCallerSESEplaceholder() ) {
+        // ignore these dummy rblocks!
+        break;
+      }
+
       if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
         
         // always remove ALL stall site taints at enter
@@ -1426,7 +1439,7 @@ public class DisjointAnalysis {
                                    );
       }
 
-      ReachGraph rgMergeOfEffects = new ReachGraph();
+      ReachGraph rgMergeOfPossibleCallers = new ReachGraph();
 
       Iterator<MethodDescriptor> mdItr = setPossibleCallees.iterator();
       while( mdItr.hasNext() ) {
@@ -1439,12 +1452,12 @@ public class DisjointAnalysis {
         // don't alter the working graph (rg) until we compute a 
         // result for every possible callee, merge them all together,
         // then set rg to that
-        ReachGraph rgCopy = new ReachGraph();
-        rgCopy.merge( rg );            
+        ReachGraph rgPossibleCaller = new ReachGraph();
+        rgPossibleCaller.merge( rg );          
                 
-        ReachGraph rgEffect = getPartial( mdPossible );
+        ReachGraph rgPossibleCallee = getPartial( mdPossible );
 
-        if( rgEffect == null ) {
+        if( rgPossibleCallee == null ) {
           // if this method has never been analyzed just schedule it 
           // for analysis and skip over this call site for now
           if( state.DISJOINTDVISITSTACKEESONTOP ) {
@@ -1460,15 +1473,22 @@ public class DisjointAnalysis {
 
         } else {
           // calculate the method call transform         
-          rgCopy.resolveMethodCall( fc, 
-                                    fmPossible, 
-                                    rgEffect,
-                                    callerNodeIDsCopiedToCallee,
-                                    writeDebugDOTs
-                                    );
+          rgPossibleCaller.resolveMethodCall( fc, 
+                                              fmPossible, 
+                                              rgPossibleCallee,
+                                              callerNodeIDsCopiedToCallee,
+                                              writeDebugDOTs
+                                              );
+
+          if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+            if( !rgPossibleCallee.isAccessible( ReachGraph.tdReturn ) ) {
+              rgPossibleCaller.makeInaccessible( fc.getReturnTemp() );
+            }
+          }
+
         }
         
-        rgMergeOfEffects.merge( rgCopy );        
+        rgMergeOfPossibleCallers.merge( rgPossibleCaller );        
       }
 
 
@@ -1480,16 +1500,25 @@ public class DisjointAnalysis {
 
       // now that we've taken care of building heap models for
       // callee analysis, finish this transformation
-      rg = rgMergeOfEffects;
+      rg = rgMergeOfPossibleCallers;
     } break;
       
 
     case FKind.FlatReturnNode:
       FlatReturnNode frn = (FlatReturnNode) fn;
       rhs = frn.getReturnTemp();
+
+      // before transfer, do effects analysis support
+      if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
+        if(!rg.isAccessible(rhs)){
+          rg.makeInaccessible(ReachGraph.tdReturn);
+        }
+      }
+
       if( rhs != null && shouldAnalysisTrack( rhs.getType() ) ) {
        rg.assignReturnEqualToTemp( rhs );
       }
+
       setRetNodes.add( frn );
       break;
 
@@ -1644,11 +1673,16 @@ public class DisjointAnalysis {
   // return just the allocation site associated with one FlatNew node
   protected AllocSite getAllocSiteFromFlatNewPRIVATE( FlatNew fnew ) {
 
+    boolean flagProgrammatically = false;
+    if( sitesToFlag != null && sitesToFlag.contains( fnew ) ) {
+      flagProgrammatically = true;
+    }
+
     if( !mapFlatNewToAllocSite.containsKey( fnew ) ) {
       AllocSite as = AllocSite.factory( allocationDepth, 
                                         fnew, 
                                         fnew.getDisjointId(),
-                                        false
+                                        flagProgrammatically
                                         );
 
       // the newest nodes are single objects