bug fix: heap contexts for call sites were propgated from caller to callee incorrectl...
authorjjenista <jjenista>
Wed, 18 May 2011 23:47:59 +0000 (23:47 +0000)
committerjjenista <jjenista>
Wed, 18 May 2011 23:47:59 +0000 (23:47 +0000)
Robust/src/Analysis/Disjoint/DisjointAnalysis.java
Robust/src/Analysis/Disjoint/ReachGraph.java
Robust/src/Benchmarks/oooJava/master-makefile
Robust/src/IR/Flat/BCXPointsToCheckVRuntime.java

index c8bde2d8b2c1bc00f8ba891cadc619020779dda4..4e851640f73ebd65bec6c66705e954d3cf0a8ec0 100644 (file)
@@ -1237,7 +1237,7 @@ public class DisjointAnalysis implements HeapAnalysis {
           stopAfterCapture
           ) {
         System.out.println("!!! Stopping analysis after debug snap captures. !!!");
-        System.exit(0);
+        System.exit(-1);
       }
     }
 
@@ -1287,7 +1287,7 @@ public class DisjointAnalysis implements HeapAnalysis {
       rg.writeGraph("genReach"+fgrn.getGraphName(),
                     true,     // write labels (variables)
                     false, //true,    // selectively hide intermediate temp vars
-                    false, //true,     // prune unreachable heap regions
+                    true,     // prune unreachable heap regions
                     true,    // hide reachability altogether
                     true,    // hide subset reachability states
                     true,     // hide predicates
@@ -1310,8 +1310,10 @@ public class DisjointAnalysis implements HeapAnalysis {
         FlatCall fc        = (FlatCall)   me.getKey();
         ReachGraph rgContrib = (ReachGraph) me.getValue();
 
-        assert fc.getMethod().equals(d);
-
+        // note that "fc.getMethod()" like (Object.toString)
+        // might not be equal to "d" like (String.toString)
+        // because the mapping gets set up when we resolve
+        // virtual dispatch
         rg.merge(rgContrib);
       }
 
@@ -1621,122 +1623,7 @@ public class DisjointAnalysis implements HeapAnalysis {
       FlatMethod fmCallee = state.getMethodFlat(mdCallee);
 
 
-
-      // all this jimma jamma to debug call sites is WELL WORTH the
-      // effort, so so so many bugs or buggy info appears through call
-      // sites
-      boolean debugCallSite = false;
-      if( state.DISJOINTDEBUGCALLEE != null &&
-          state.DISJOINTDEBUGCALLER != null ) {
-
-        boolean debugCalleeMatches = false;
-        boolean debugCallerMatches = false;
-        
-        ClassDescriptor cdCallee = mdCallee.getClassDesc();
-        if( cdCallee != null ) {
-          debugCalleeMatches = 
-            state.DISJOINTDEBUGCALLEE.equals( cdCallee.getSymbol()+
-                                              "."+
-                                              mdCallee.getSymbol()
-                                              );
-        }
-
-
-        if( mdCaller instanceof MethodDescriptor ) {
-          ClassDescriptor cdCaller = ((MethodDescriptor)mdCaller).getClassDesc();
-          if( cdCaller != null ) {
-            debugCallerMatches = 
-              state.DISJOINTDEBUGCALLER.equals( cdCaller.getSymbol()+
-                                                "."+
-                                                mdCaller.getSymbol()
-                                                );
-          }        
-        } else {
-          // for bristlecone style tasks
-          debugCallerMatches =
-            state.DISJOINTDEBUGCALLER.equals( mdCaller.getSymbol() );
-        }
-
-        debugCallSite = debugCalleeMatches && debugCallerMatches;
-      }
-
       
-
-
-      boolean writeDebugDOTs = false;
-      boolean stopAfter      = false;
-      if( debugCallSite ) {
-        ++ReachGraph.debugCallSiteVisitCounter;
-        System.out.println("    $$$ Debug call site visit "+
-                           ReachGraph.debugCallSiteVisitCounter+
-                           " $$$"
-                           );
-        if(
-          (ReachGraph.debugCallSiteVisitCounter >=
-           ReachGraph.debugCallSiteVisitStartCapture)  &&
-
-          (ReachGraph.debugCallSiteVisitCounter <
-           ReachGraph.debugCallSiteVisitStartCapture +
-           ReachGraph.debugCallSiteNumVisitsToCapture)
-          ) {
-          writeDebugDOTs = true;
-          System.out.println("      $$$ Capturing this call site visit $$$");
-          if( ReachGraph.debugCallSiteStopAfter &&
-              (ReachGraph.debugCallSiteVisitCounter ==
-               ReachGraph.debugCallSiteVisitStartCapture +
-               ReachGraph.debugCallSiteNumVisitsToCapture - 1)
-              ) {
-            stopAfter = true;
-          }
-        }
-      }
-
-
-      // calculate the heap this call site can reach--note this is
-      // not used for the current call site transform, we are
-      // grabbing this heap model for future analysis of the callees,
-      // so if different results emerge we will return to this site
-      ReachGraph heapForThisCall_old =
-        getIHMcontribution(mdCallee, fc);
-
-      // the computation of the callee-reachable heap
-      // is useful for making the callee starting point
-      // and for applying the call site transfer function
-      Set<Integer> callerNodeIDsCopiedToCallee =
-        new HashSet<Integer>();
-
-      ReachGraph heapForThisCall_cur =
-        rg.makeCalleeView(fc,
-                          fmCallee,
-                          callerNodeIDsCopiedToCallee,
-                          writeDebugDOTs
-                          );
-
-      // enforce that a call site contribution can only
-      // monotonically increase
-      heapForThisCall_cur.merge(heapForThisCall_old);
-
-      if( !heapForThisCall_cur.equals(heapForThisCall_old) ) {
-        // if heap at call site changed, update the contribution,
-        // and reschedule the callee for analysis
-        addIHMcontribution(mdCallee, fc, heapForThisCall_cur);
-
-        // map a FlatCall to its enclosing method/task descriptor
-        // so we can write that info out later
-        fc2enclosing.put(fc, mdCaller);
-
-        if( state.DISJOINTDEBUGSCHEDULING ) {
-          System.out.println("  context changed, scheduling callee: "+mdCallee);
-        }
-
-        if( state.DISJOINTDVISITSTACKEESONTOP ) {
-          calleesToEnqueue.add(mdCallee);
-        } else {
-          enqueue(mdCallee);
-        }
-
-      }
-
       // the transformation for a call site should update the
       // current heap abstraction with any effects from the callee,
       // or if the method is virtual, the effects from any possible
@@ -1760,9 +1647,11 @@ public class DisjointAnalysis implements HeapAnalysis {
       }
 
 
-
+      DebugCallSiteData dcsd = new DebugCallSiteData();
+      
       ReachGraph rgMergeOfPossibleCallers = new ReachGraph();
 
+
       Iterator<MethodDescriptor> mdItr = setPossibleCallees.iterator();
       while( mdItr.hasNext() ) {
         MethodDescriptor mdPossible = mdItr.next();
@@ -1771,6 +1660,60 @@ public class DisjointAnalysis implements HeapAnalysis {
         addDependent(mdPossible,  // callee
                      d);          // caller
 
+
+        // decide for each possible resolution of the method whether we
+        // want to debug this call site
+        decideDebugCallSite( dcsd, mdCaller, mdPossible );
+
+
+
+        // calculate the heap this call site can reach--note this is
+        // not used for the current call site transform, we are
+        // grabbing this heap model for future analysis of the callees,
+        // so if different results emerge we will return to this site
+        ReachGraph heapForThisCall_old =
+          getIHMcontribution(mdPossible, fc);
+      
+        // the computation of the callee-reachable heap
+        // is useful for making the callee starting point
+        // and for applying the call site transfer function
+        Set<Integer> callerNodeIDsCopiedToCallee =
+          new HashSet<Integer>();
+
+        ReachGraph heapForThisCall_cur =
+          rg.makeCalleeView(fc,
+                            fmPossible,
+                            callerNodeIDsCopiedToCallee,
+                            dcsd.writeDebugDOTs
+                            );
+
+        // enforce that a call site contribution can only
+        // monotonically increase
+        heapForThisCall_cur.merge(heapForThisCall_old);
+
+        if( !heapForThisCall_cur.equals(heapForThisCall_old) ) {
+          // if heap at call site changed, update the contribution,
+          // and reschedule the callee for analysis
+          addIHMcontribution(mdPossible, fc, heapForThisCall_cur);
+
+          // map a FlatCall to its enclosing method/task descriptor
+          // so we can write that info out later
+          fc2enclosing.put(fc, mdCaller);
+
+          if( state.DISJOINTDEBUGSCHEDULING ) {
+            System.out.println("  context changed, scheduling callee: "+mdPossible);
+          }
+
+          if( state.DISJOINTDVISITSTACKEESONTOP ) {
+            calleesToEnqueue.add(mdPossible);
+          } else {
+            enqueue(mdPossible);
+          }
+        }
+
+
+        
+
         // 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
@@ -1792,17 +1735,19 @@ public class DisjointAnalysis implements HeapAnalysis {
             System.out.println("  callee hasn't been analyzed, scheduling: "+mdPossible);
           }
 
+
         } else {
+          
           // calculate the method call transform
           rgPossibleCaller.resolveMethodCall(fc,
                                              fmPossible,
                                              rgPossibleCallee,
                                              callerNodeIDsCopiedToCallee,
-                                             writeDebugDOTs
+                                             dcsd.writeDebugDOTs
                                              );
 
+
           if( doEffectsAnalysis && fmContaining != fmAnalysisEntry ) {
-//            if( !rgPossibleCallee.isAccessible( ReachGraph.tdReturn ) ) {
             if( !accessible.isAccessible(fn, ReachGraph.tdReturn) ) {
               rgPossibleCaller.makeInaccessible(fc.getReturnTemp() );
             }
@@ -1812,12 +1757,9 @@ public class DisjointAnalysis implements HeapAnalysis {
 
         rgMergeOfPossibleCallers.merge(rgPossibleCaller);
       }
+      
 
-
-      if( stopAfter ) {
-        System.out.println("$$$ Exiting after requested captures of call site. $$$");
-        System.exit(0);
-      }
+      statusDebugCallSite( dcsd );
 
 
       // now that we've taken care of building heap models for
@@ -2872,6 +2814,114 @@ public class DisjointAnalysis implements HeapAnalysis {
     return fn2rgAtEnter.get(fn);
   }
 
+
+
+  protected class DebugCallSiteData {
+    public boolean debugCallSite;
+    public boolean didOneDebug;
+    public boolean writeDebugDOTs;
+    public boolean stopAfter;
+
+    public DebugCallSiteData() {
+      debugCallSite  = false;
+      didOneDebug    = false;
+      writeDebugDOTs = false;
+      stopAfter      = false;
+    }
+  }
+
+  protected void decideDebugCallSite( DebugCallSiteData dcsd,
+                                      Descriptor        taskOrMethodCaller,
+                                      MethodDescriptor  mdCallee ) {
+    
+    // all this jimma jamma to debug call sites is WELL WORTH the
+    // effort, so so so many bugs or buggy info appears through call
+    // sites
+
+    if( state.DISJOINTDEBUGCALLEE == null ||
+        state.DISJOINTDEBUGCALLER == null ) {
+      return;
+    }
+
+
+    boolean debugCalleeMatches = false;
+    boolean debugCallerMatches = false;
+        
+    ClassDescriptor cdCallee = mdCallee.getClassDesc();
+    if( cdCallee != null ) {
+      debugCalleeMatches = 
+        state.DISJOINTDEBUGCALLEE.equals( cdCallee.getSymbol()+
+                                          "."+
+                                          mdCallee.getSymbol()
+                                          );
+    }
+
+
+    if( taskOrMethodCaller instanceof MethodDescriptor ) {
+      ClassDescriptor cdCaller = ((MethodDescriptor)taskOrMethodCaller).getClassDesc();
+      if( cdCaller != null ) {
+        debugCallerMatches = 
+          state.DISJOINTDEBUGCALLER.equals( cdCaller.getSymbol()+
+                                            "."+
+                                            taskOrMethodCaller.getSymbol()
+                                            );
+      }        
+    } else {
+      // for bristlecone style tasks
+      debugCallerMatches =
+        state.DISJOINTDEBUGCALLER.equals( taskOrMethodCaller.getSymbol() );
+    }
+
+    dcsd.debugCallSite = debugCalleeMatches && debugCallerMatches;
+    dcsd.writeDebugDOTs = dcsd.debugCallSite;
+
+    if( dcsd.debugCallSite ) {
+      dcsd.didOneDebug = true;
+      System.out.println( "       --> Debugging "+taskOrMethodCaller+" calling "+mdCallee );
+    }
+  }
+
+  protected void statusDebugCallSite( DebugCallSiteData dcsd ) {
+
+    dcsd.writeDebugDOTs = false;
+    dcsd.stopAfter      = false;
+
+    if( dcsd.didOneDebug ) {
+      ++ReachGraph.debugCallSiteVisitCounter;
+      System.out.println("    $$$ Debug call site visit "+
+                         ReachGraph.debugCallSiteVisitCounter+
+                         " $$$"
+                         );
+      if(
+         (ReachGraph.debugCallSiteVisitCounter >=
+          ReachGraph.debugCallSiteVisitStartCapture)  &&
+         
+         (ReachGraph.debugCallSiteVisitCounter <
+          ReachGraph.debugCallSiteVisitStartCapture +
+          ReachGraph.debugCallSiteNumVisitsToCapture)
+         ) {
+        dcsd.writeDebugDOTs = true;
+        System.out.println("      $$$ Capturing this call site visit $$$");
+        if( ReachGraph.debugCallSiteStopAfter &&
+            (ReachGraph.debugCallSiteVisitCounter ==
+             ReachGraph.debugCallSiteVisitStartCapture +
+             ReachGraph.debugCallSiteNumVisitsToCapture - 1)
+            ) {
+          dcsd.stopAfter = true;
+        }
+      }
+    }
+
+    if( dcsd.stopAfter ) {
+      System.out.println("$$$ Exiting after requested captures of call site. $$$");
+      System.exit(-1);
+    }
+  }
+  
+
+
+
+
   // get successive captures of the analysis state, use compiler
   // flags to control
   boolean takeDebugSnapshots = false;
index 6eedd6ba33374576d5dc230d3447b230b10450b5..c64b2abe3ec00f2bbdc1830d3eaa80e36282a7cf 100644 (file)
@@ -4466,7 +4466,9 @@ public class ReachGraph {
     try {
       // remove all non-word characters from the graph name so
       // the filename and identifier in dot don't cause errors
-      graphName = graphName.replaceAll("[\\W]", "");
+      // jjenista - also replace underscore '_' to prevent some
+      // really, really long names from IHMS debugging
+      graphName = graphName.replaceAll("[\\W_]", "");
 
       BufferedWriter bw =
         new BufferedWriter(new FileWriter(graphName+".dot") );
index debd68cf2c27269d796fa540a6b1e2d3c8099350..2f7415108090b8699f9e5dbed1766351246c9fa7 100644 (file)
@@ -40,7 +40,7 @@ RCRDEBUGV= -rcr_debug_verbose -printlinenum
 BSFLAGS= -64bit -mainclass $(PROGRAM)  -heapsize-mb 5000 -garbagestats -joptimize -noloop -optimize -nolock -debug #-nooptimize #src-after-pp
 
 
-CHECKPOINTSTO= -printlinenum -pointsto-check-v-runtime
+CHECKPOINTSTO= -printlinenum -pointsto-check-v-runtime -debug
 
 
 DRELEASEMODE=-disjoint-release-mode -disjoint-dvisit-stack-callees-on-top -disjoint-alias-file aliases.txt tabbed
@@ -76,16 +76,18 @@ DISJOINT= -disjoint -disjoint-k 1 -enable-assertions $(DRELEASEMODE) #-disjoint-
 # EX: (skip first 10 visits, capture the next 3, then halt)
 # -disjoint-debug-snap-method Remove 10 3 true
 
-DISJOINTDEBUG= -disjoint -disjoint-k 1 -enable-assertions \
-       -disjoint-write-dots final \
-       -flatirusermethods
-#       -disjoint-debug-callsite String.valueOf Power.main 1 1000 true \
+DISJOINTDEBUG= -disjoint -disjoint-k 1 -enable-assertions
+#      -disjoint-debug-callsite String.toString String.valueOf 1 1000 true \
+#      -disjoint-debug-snap-method String.toString 1 1000 true \
+#      -disjoint-write-initial-contexts \
+#      -disjoint-write-dots final
+#      -disjoint-debug-scheduling \
+#      -disjoint-write-ihms
+#      -flatirusermethods
 #       -justanalyze
 #      -disjoint-desire-determinism
 #      -disjoint-debug-callsite Demand.add Lateral.compute 1 1000 true
 #      -disjoint-debug-snap-method ComputeCenterOfMass 6 2 true
-#      -disjoint-debug-scheduling
-
 
 
 
@@ -99,6 +101,10 @@ single-remake-c:
 rcr-remake-c:
        $(BUILDSCRIPT) -nojava $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) $(USERCR) $(DISJOINT) -o $(PROGRAM)r -builddir rcr  $(SOURCE_FILES) 
 
+check-remake-c:
+       $(BUILDSCRIPT) -nojava $(BMFLAGS) $(BSFLAGS) $(USECOREPROF) $(DISJOINTDEBUG) $(CHECKPOINTSTO) -o $(PROGRAM)c -builddir chk $(SOURCE_FILES)
+
+
 
 single: $(PROGRAM)s.bin
 
index 2ab300ac36d27a0d3a2656fd12a1f5cc8263d8fb..6f8a98795ba49b6dbb636869e2c355e38c7aa119 100644 (file)
@@ -34,6 +34,7 @@ public class BCXPointsToCheckVRuntime implements BuildCodeExtension {
 
   public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {    
     outmethodheader.println( "#include<stdio.h>" );
+    outmethodheader.println( "#include<execinfo.h>" );
   }
 
 
@@ -216,6 +217,21 @@ public class BCXPointsToCheckVRuntime implements BuildCodeExtension {
                     condition+" ) allocsite=%d at %s:%d\\n\", ((struct "+
                     cdObject.getSafeSymbol()+"*)"+
                     pointer+")->allocsite, __FILE__, __LINE__ );" );
+
+    // spit out the stack trace (so fancy!)
+    output.println( "{" );
+    output.println( "void* buffer[100];" );
+    output.println( "char** strings;" );
+    output.println( "int nptrs,j;" );
+    output.println( "nptrs = backtrace(buffer, 100);" );
+    output.println( "strings = backtrace_symbols(buffer, nptrs);" );
+    output.println( "if (strings == NULL) {" );
+    output.println( "  perror(\"backtrace_symbols\");" );
+    output.println( "}" );
+    output.println( "for (j = 0; j < nptrs; j++) {" );
+    output.println( "  printf(\"%s\\n\", strings[j]);" );
+    output.println( "}" );
+    output.println( "}" );
   }