adds new option '-nostalltr' that turns off rcr traversers that only handle conflicts...
[IRC.git] / Robust / src / IR / Flat / RuntimeConflictResolver.java
index aeaa40509dd694f342fae826729e2ec4b5b44424..f5827ef0f18400f410c64fcd021a69793c893a79 100644 (file)
@@ -12,7 +12,10 @@ import java.util.Vector;
 import Util.Tuple;
 import Analysis.Disjoint.*;
 import Analysis.MLP.CodePlan;
+import IR.State;
 import IR.TypeDescriptor;
+import Analysis.OoOJava.ConflictGraph;
+import Analysis.OoOJava.ConflictNode;
 import Analysis.OoOJava.OoOJavaAnalysis;
 
 /* An instance of this class manages all OoOJava coarse-grained runtime conflicts
@@ -28,7 +31,11 @@ import Analysis.OoOJava.OoOJavaAnalysis;
  * Note: All computation is done upon closing the object. Steps 1-3 only input data
  */
 public class RuntimeConflictResolver {
-  public static final boolean javaDebug = true;
+  public static final boolean generalDebug = true;
+//Prints out effects and data structure used to steer RCR traversals
+  public static final boolean printEffectsAndEffectsTable = false;  
+//Prints steps taken to build internal representation of pruned reach graph
+  public static final boolean traceDataStructureBuild = false;  
   public static final boolean cSideDebug = false;
   
   private PrintWriter cFile;
@@ -38,6 +45,7 @@ public class RuntimeConflictResolver {
   //The Integer keeps track of the weakly connected group it's in (used in enumerateHeapRoots)
   private Hashtable<Taint, Integer> doneTaints;
   private Hashtable<Tuple, Integer> idMap=new Hashtable<Tuple,Integer>();
+  private Hashtable<Tuple, Integer> weakMap=new Hashtable<Tuple,Integer>();
   private Hashtable<Taint, Set<Effect>> globalEffects;
   private Hashtable<Taint, Set<Effect>> globalConflicts;
   private ArrayList<TraversalInfo> toTraverse;
@@ -63,10 +71,12 @@ public class RuntimeConflictResolver {
   private ArrayList<TaintAndInternalHeapStructure> pendingPrintout;
   private EffectsTable effectsLookupTable;
   private OoOJavaAnalysis oooa;
+  private State state;
 
-  public RuntimeConflictResolver(String buildir, OoOJavaAnalysis oooa) throws FileNotFoundException {
+  public RuntimeConflictResolver(String buildir, OoOJavaAnalysis oooa, State state) throws FileNotFoundException {
     String outputFile = buildir + "RuntimeConflictResolver";
     this.oooa=oooa;
+    this.state=state;
 
     cFile = new PrintWriter(new File(outputFile + ".c"));
     headerFile = new PrintWriter(new File(outputFile + ".h"));
@@ -96,7 +106,7 @@ public class RuntimeConflictResolver {
   public void setGlobalEffects(Hashtable<Taint, Set<Effect>> effects) {
     globalEffects = effects;
     
-    if(javaDebug) {
+    if(printEffectsAndEffectsTable) {
       System.out.println("============EFFECTS LIST AS PASSED IN============");
       for(Taint t: globalEffects.keySet()) {
         System.out.println("For Taint " + t);
@@ -118,17 +128,29 @@ public class RuntimeConflictResolver {
       System.out.println(fsen);
       System.out.println(fsen.getIsCallerSESEplaceholder());
       System.out.println(fsen.getParent());
-
-      if (fsen.getParent() != null) {
-        conflictGraph = oooa.getConflictGraph(fsen.getParent());
+      
+//      if (fsen.getParent() != null) {
+      FlatSESEEnterNode parentSESE = null;
+      if (fsen.getSESEParent().size() > 0) {
+         parentSESE = (FlatSESEEnterNode) fsen.getSESEParent().iterator().next();
+        System.out.println("fsen getParent=" + parentSESE);
+        conflictGraph = oooa.getConflictGraph(parentSESE);
         System.out.println("CG=" + conflictGraph);
         if (conflictGraph != null)
           System.out.println("Conflicts=" + conflictGraph.getConflictEffectSet(fsen));
+        // conflictGraph = oooa.getConflictGraph(fsen.getParent());
+        // System.out.println("CG=" + conflictGraph);
+        // if (conflictGraph != null)
+        // System.out.println("Conflicts=" +
+        // conflictGraph.getConflictEffectSet(fsen));
       }
 
-      if (!fsen.getIsCallerSESEplaceholder() && fsen.getParent() != null
-          && (conflictGraph = oooa.getConflictGraph(fsen.getParent())) != null
-          && (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null) {
+//      if (!fsen.getIsCallerSESEplaceholder() && fsen.getParent() != null
+//          && (conflictGraph = oooa.getConflictGraph(fsen.getParent())) != null
+//          && (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null) {
+      if(!fsen.getIsCallerSESEplaceholder() && fsen.getSESEParent().size() > 0
+          && (conflictGraph = oooa.getConflictGraph(parentSESE)) != null
+          && (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null ){
         FlatMethod fm = fsen.getfmEnclosing();
         ReachGraph rg = oooa.getDisjointAnalysis().getReachGraph(fm.getMethod());
         if (cSideDebug)
@@ -142,7 +164,13 @@ public class RuntimeConflictResolver {
       FlatNode fn = codeit.next();
       CodePlan cp = oooa.getCodePlan(fn);
       FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
-      Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE);
+      
+      if(currentSESE.getSESEParent().size()==0){
+        continue;
+      }
+      FlatSESEEnterNode parent=(FlatSESEEnterNode)currentSESE.getSESEParent().iterator().next();
+//      Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE);
+      Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent);
 
       if (graph != null) {
         Set<Analysis.OoOJava.SESELock> seseLockSet = oooa.getLockMappings(graph);
@@ -237,7 +265,7 @@ public class RuntimeConflictResolver {
       VariableNode varNode = rg.getVariableNodeNoMutation(invar);
       Taint taint = getProperTaintForFlatSESEEnterNode(rblock, varNode, globalEffects);
       if (taint == null) {
-        printDebug(javaDebug, "Null FOR " +varNode.getTempDescriptor().getSafeSymbol() + rblock.toPrettyString());
+        printDebug(generalDebug, "Null FOR " +varNode.getTempDescriptor().getSafeSymbol() + rblock.toPrettyString());
         continue;
       }
       
@@ -280,7 +308,7 @@ public class RuntimeConflictResolver {
     Taint taint = getProperTaintForEnterNode(enterNode, varNode, globalEffects);
     
     if (taint == null) {
-      printDebug(javaDebug, "Null FOR " +varNode.getTempDescriptor().getSafeSymbol() + enterNode.toString());
+      printDebug(generalDebug, "Null FOR " +varNode.getTempDescriptor().getSafeSymbol() + enterNode.toString());
       return;
     }        
     
@@ -307,6 +335,10 @@ public class RuntimeConflictResolver {
     removeInvalidChars(flatname) + "___("+varString+");";
   }
 
+  public int getWeakID(TempDescriptor invar, FlatNode fn) {
+    return weakMap.get(new Tuple(invar, fn)).intValue();
+  }
+
   public int getTraverserID(TempDescriptor invar, FlatNode fn) {
     Tuple t=new Tuple(invar, fn);
     if (idMap.containsKey(t))
@@ -362,7 +394,7 @@ public class RuntimeConflictResolver {
 
   private void runAllTraversals() {
     for(TraversalInfo t: toTraverse) {
-      printDebug(javaDebug, "Running Traversal a traversal on " + t.f);
+      printDebug(generalDebug, "Running Traversal a traversal on " + t.f);
       
       if(t.f instanceof FlatSESEEnterNode) {
         traverseSESEBlock((FlatSESEEnterNode)t.f, t.rg);
@@ -379,20 +411,27 @@ public class RuntimeConflictResolver {
 
   //TODO: This is only temporary, remove when thread local variables are functional. 
   private void createMasterHashTableArray() {
-    headerFile.println("void createAndFillMasterHashStructureArray();");
-    cFile.println("void createAndFillMasterHashStructureArray() {\n" +
-               "  rcr_createMasterHashTableArray("+weaklyConnectedHRCounter + ");");
+    headerFile.println("struct Hashtable_rcr ** createAndFillMasterHashStructureArray();");
+    cFile.println("struct Hashtable_rcr ** createAndFillMasterHashStructureArray() {");
+    cFile.println("  struct Hashtable_rcr **table=rcr_createMasterHashTableArray("+weaklyConnectedHRCounter + ");");
     
     for(int i = 0; i < weaklyConnectedHRCounter; i++) {
-      cFile.println("  allHashStructures["+i+"] = (HashStructure *) rcr_createHashtable("+num2WeaklyConnectedHRGroup.get(i).connectedHRs.size()+");");
+      cFile.println("  table["+i+"] = (struct Hashtable_rcr *) rcr_createHashtable("+num2WeaklyConnectedHRGroup.get(i).connectedHRs.size()+");");
     }
+    cFile.println("  return table;");
     cFile.println("}");
   }
 
   private void printMasterTraverserInvocation() {
     headerFile.println("\nint tasktraverse(SESEcommon * record);");
     cFile.println("\nint tasktraverse(SESEcommon * record) {");
-    cFile.println("  if(!CAS(&record->rcrstatus,1,2)) return;");
+    cFile.println("  if(!CAS(&record->rcrstatus,1,2)) {");
+    //release traverser reference...no traversal necessary
+    cFile.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
+    cFile.println("    RELEASE_REFERENCE_TO(record);");
+    cFile.println("#endif");
+    cFile.println("    return;");
+    cFile.println("  }");
     cFile.println("  switch(record->classID) {");
     
     for(Iterator<FlatSESEEnterNode> seseit=oooa.getAllSESEs().iterator();seseit.hasNext();) {
@@ -403,8 +442,30 @@ public class RuntimeConflictResolver {
       Vector<TempDescriptor> invars=fsen.getInVarsForDynamicCoarseConflictResolution();
       for(int i=0;i<invars.size();i++) {
         TempDescriptor tmp=invars.get(i);
-        cFile.println("      " + this.getTraverserInvocation(tmp, "rec->"+tmp+", rec", fsen));
+        
+        // FIX IT LATER! Right now, we assume that there is only one parent
+        FlatSESEEnterNode parentSESE = (FlatSESEEnterNode) fsen.getSESEParent().iterator().next();
+        ConflictGraph graph=oooa.getConflictGraph(parentSESE);
+        String id = tmp + "_sese" + fsen.getPrettyIdentifier();
+        ConflictNode node = graph.getId2cn().get(id);        
+        
+       if (i!=0) {
+           cFile.println("      if (record->rcrstatus!=0)");
+       }
+       
+        if(state.NOSTALLTR && node.IsValidToPrune()){
+          cFile.println("    /*  " + this.getTraverserInvocation(tmp, "rec->"+tmp+", rec", fsen)+"*/");
+        }else{
+          cFile.println("      " + this.getTraverserInvocation(tmp, "rec->"+tmp+", rec", fsen));
+        }
+        
       }
+      //release traverser reference...traversal finished...
+      //executing thread will clean bins for us
+      cFile.println("     record->rcrstatus=0;");
+      cFile.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
+      cFile.println("    RELEASE_REFERENCE_TO(record);");
+      cFile.println("#endif");
       cFile.println(    "    }");
       cFile.println(    "    break;");
     }
@@ -414,13 +475,13 @@ public class RuntimeConflictResolver {
         cFile.println(    "    case -" + getTraverserID(t.getVar(), t.getStallSite())+ ": {");
         cFile.println(    "      SESEstall * rec=(SESEstall*) record;");
         cFile.println(    "      " + this.getTraverserInvocation(t.getVar(), "rec->___obj___, rec", t.getStallSite())+";");
+       cFile.println(    "     record->rcrstatus=0;");
         cFile.println(    "    }");
         cFile.println("    break;");
       }
     }
 
     cFile.println("    default:\n    printf(\"Invalid SESE ID was passed in: %d.\\n\",record->classID);\n    break;");
-    
     cFile.println("  }");
     cFile.println("}");
   }
@@ -625,9 +686,9 @@ public class RuntimeConflictResolver {
     
     //Generate C cases 
     for (ConcreteRuntimeObjNode node : created.values()) {
-      printDebug(javaDebug, "Considering " + node.allocSite + " for traversal");
+      printDebug(generalDebug, "Considering " + node.allocSite + " for traversal");
       if (!cases.containsKey(node.allocSite) && qualifiesForCaseStatement(node)) {
-        printDebug(javaDebug, "+\t" + node.allocSite + " qualified for case statement");
+        printDebug(generalDebug, "+\t" + node.allocSite + " qualified for case statement");
         addChecker(taint, node, cases, null, "ptr", 0);
       }
     }
@@ -655,13 +716,11 @@ public class RuntimeConflictResolver {
     if(cases.size() == 0) {
       cFile.println(" return;");
     } else {
-      cFile.println("    int totalcount=RUNBIAS;\n");
-      
+      cFile.println("    int totalcount=RUNBIAS;");      
       if (taint.isStallSiteTaint()) {
-        cFile.println("    record->rcrRecords[0].count=RUNBIAS;\n");
+        cFile.println("    record->rcrRecords[0].count=RUNBIAS;");
       } else {
-        cFile.println("    record->rcrRecords["+index+"].count=RUNBIAS;\n");
-        cFile.println("    record->rcrRecords["+index+"].index=0;\n");
+        cFile.println("    record->rcrRecords["+index+"].count=RUNBIAS;");
       }
       
       //clears queue and hashtable that keeps track of where we've been. 
@@ -685,20 +744,18 @@ public class RuntimeConflictResolver {
       
       if (taint.isStallSiteTaint()) {
         //need to add this
-        cFile.println("     if(atomic_sub_and_test(RUNBIAS-totalcount,&(record->rcrRecords[0].count))) {");
+        cFile.println("     if(atomic_sub_and_test(totalcount,&(record->rcrRecords[0].count))) {");
         cFile.println("         psem_give_tag(record->common.parentsStallSem, record->tag);");
         cFile.println("         BARRIER();");
-        cFile.println("         record->common.rcrstatus=0;");
         cFile.println("}");
       } else {
-        cFile.println("     if(atomic_sub_and_test(RUNBIAS-totalcount,&(record->rcrRecords["+index+"].count))) {");
+        cFile.println("     if(atomic_sub_and_test(totalcount,&(record->rcrRecords["+index+"].count))) {");
         cFile.println("        int flag=LOCKXCHG32(&(record->rcrRecords["+index+"].flag),0);");
         cFile.println("        if(flag) {");
         //we have resolved a heap root...see if this was the last dependence
         cFile.println("            if(atomic_sub_and_test(1, &(record->common.unresolvedDependencies))) workScheduleSubmit((void *)record);");
         cFile.println("        }");
         cFile.println("     }");
-        cFile.println("     record->common.rcrstatus=0;");
       }
     }
     cFile.println("}");
@@ -727,27 +784,76 @@ public class RuntimeConflictResolver {
     //either currCase is continuing off a parent case or is its own. 
     assert currCase !=null;
     
+    insertEntriesIntoHashStructure(taint, node, prefix, depth, currCase);
+    
+    //Handle conflicts further down. 
+    if(node.decendantsConflict()) {
+      int pdepth=depth+1;
+      currCase.append("{\n");
+      
+      //Array Case
+      if(node.isArray() && node.decendantsConflict()) {
+        String childPtr = "((struct ___Object___ **)(((char *) &(((struct ArrayObject *)"+ prefix+")->___length___))+sizeof(int)))[i]";
+        String currPtr = "arrayElement" + pdepth;
+        
+        currCase.append("{\n  int i;\n");
+        currCase.append("    struct ___Object___ * "+currPtr+";\n");
+        currCase.append("  for(i = 0; i<((struct ArrayObject *) " + prefix + " )->___length___; i++ ) {\n");
+        
+        //There should be only one field, hence we only take the first field in the keyset.
+        assert node.objectRefs.keySet().size() <= 1;
+        ObjRefList refsAtParticularField = node.objectRefs.get(node.objectRefs.keySet().iterator().next());
+        printObjRefSwitchStatement(taint,cases,pdepth,currCase,refsAtParticularField,childPtr,currPtr);
+        currCase.append("      }}\n");
+      } else {
+      //All other cases
+        String currPtr = "myPtr" + pdepth;
+        currCase.append("    struct ___Object___ * "+currPtr+";\n");
+        for(String field: node.objectRefs.keySet()) {
+          ObjRefList refsAtParticularField = node.objectRefs.get(field);
+          
+          if(refsAtParticularField.hasConflicts()) {
+            String childPtr = "((struct "+node.original.getType().getSafeSymbol()+" *)"+prefix +")->___" + field + "___";
+            printObjRefSwitchStatement(taint,cases, pdepth, currCase, refsAtParticularField, childPtr, currPtr);
+          }
+        }      
+      }
+      
+      currCase.append("}\n"); //For particular top level case statement. 
+    }
+    if(qualifiesForCaseStatement(node)) {
+      currCase.append("  }\n  break;\n");
+    }
+  }
+
+  private void insertEntriesIntoHashStructure(Taint taint, ConcreteRuntimeObjNode curr,
+      String prefix, int depth, StringBuilder currCase) {
     boolean primConfRead=false;
     boolean primConfWrite=false;
     boolean objConfRead=false;
     boolean objConfWrite=false;
+    boolean descendantConflict=false;
 
     //Direct Primitives Test
-    for(String field: node.primitiveConflictingFields.keySet()) {
-      CombinedObjEffects effect=node.primitiveConflictingFields.get(field);
+    for(String field: curr.primitiveConflictingFields.keySet()) {
+      CombinedObjEffects effect=curr.primitiveConflictingFields.get(field);
       primConfRead|=effect.hasReadConflict;
       primConfWrite|=effect.hasWriteConflict;
     }
 
     //Direct Object Reference Test
-    for(String field: node.objectRefs.keySet()) {
-      for(ObjRef ref: node.objectRefs.get(field)) {
+    for(String field: curr.objectRefs.keySet()) {
+      for(ObjRef ref: curr.objectRefs.get(field)) {
         CombinedObjEffects effect=ref.myEffects;
         objConfRead|=effect.hasReadConflict;
         objConfWrite|=effect.hasWriteConflict;
       }
     }
 
+    if (objConfRead) {
+       descendantConflict=curr.decendantsConflict();
+    }
+
     int index=0;
     if (taint.isRBlockTaint()) {
       FlatSESEEnterNode fsese=taint.getSESE();
@@ -756,26 +862,26 @@ public class RuntimeConflictResolver {
     }
 
     String strrcr=taint.isRBlockTaint()?"&record->rcrRecords["+index+"], ":"NULL, ";
-    String tasksrc=taint.isRBlockTaint()?"(SESEcommon *) record, ":"(SESEcommon *)(((INTPTR)record)&1LL), ";
+    String tasksrc=taint.isRBlockTaint()?"(SESEcommon *) record, ":"(SESEcommon *)(((INTPTR)record)|1LL), ";
     
     //Do call if we need it.
     if(primConfWrite||objConfWrite) {
       int heaprootNum = connectedHRHash.get(taint).id;
       assert heaprootNum != -1;
-      int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(node);
+      int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(curr);
       int traverserID = doneTaints.get(taint);
         currCase.append("    int tmpkey"+depth+"=rcr_generateKey("+prefix+");\n");
-      if (objConfRead)
+      if (descendantConflict)
         currCase.append("    int tmpvar"+depth+"=rcr_WTWRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", "+tasksrc+strrcr+index+");\n");
       else
         currCase.append("    int tmpvar"+depth+"=rcr_WRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", "+ tasksrc+strrcr+index+");\n");
     } else if (primConfRead||objConfRead) {
       int heaprootNum = connectedHRHash.get(taint).id;
       assert heaprootNum != -1;
-      int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(node);
+      int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(curr);
       int traverserID = doneTaints.get(taint);
       currCase.append("    int tmpkey"+depth+"=rcr_generateKey("+prefix+");\n");
-      if (objConfRead) 
+      if (descendantConflict)
         currCase.append("    int tmpvar"+depth+"=rcr_WTREADBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", "+tasksrc+strrcr+index+");\n");
       else
         currCase.append("    int tmpvar"+depth+"=rcr_READBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", "+tasksrc+strrcr+index+");\n");
@@ -784,45 +890,6 @@ public class RuntimeConflictResolver {
     if(primConfWrite||objConfWrite||primConfRead||objConfRead) {
       currCase.append("if (!(tmpvar"+depth+"&READYMASK)) totalcount--;\n");
     }
-    
-    //Handle conflicts further down. 
-    if(node.decendantsConflict()) {
-      int pdepth=depth+1;
-      currCase.append("{\n");
-      
-      //Array Case
-      if(node.isArray() && node.decendantsConflict()) {
-        String childPtr = "((struct ___Object___ **)(((char *) &(((struct ArrayObject *)"+ prefix+")->___length___))+sizeof(int)))[i]";
-        String currPtr = "arrayElement" + pdepth;
-        
-        currCase.append("{\n  int i;\n");
-        currCase.append("    struct ___Object___ * "+currPtr+";\n");
-        currCase.append("  for(i = 0; i<((struct ArrayObject *) " + prefix + " )->___length___; i++ ) {\n");
-        
-        //There should be only one field, hence we only take the first field in the keyset.
-        assert node.objectRefs.keySet().size() <= 1;
-        ObjRefList refsAtParticularField = node.objectRefs.get(node.objectRefs.keySet().iterator().next());
-        printObjRefSwitchStatement(taint,cases,pdepth,currCase,refsAtParticularField,childPtr,currPtr);
-        currCase.append("      }}\n");
-      } else {
-      //All other cases
-        String currPtr = "myPtr" + pdepth;
-        currCase.append("    struct ___Object___ * "+currPtr+";\n");
-        for(String field: node.objectRefs.keySet()) {
-          ObjRefList refsAtParticularField = node.objectRefs.get(field);
-          
-          if(refsAtParticularField.hasConflicts()) {
-            String childPtr = "((struct "+node.original.getType().getSafeSymbol()+" *)"+prefix +")->___" + field + "___";
-            printObjRefSwitchStatement(taint, cases, depth, currCase, refsAtParticularField, childPtr, currPtr);
-          }
-        }      
-      }
-      
-      currCase.append("}\n"); //For particular top level case statement. 
-    }
-    if(qualifiesForCaseStatement(node)) {
-      currCase.append("  }\n  break;\n");
-    }
   }
 
   private void printObjRefSwitchStatement(Taint taint, Hashtable<AllocSite, StringBuilder> cases,
@@ -839,18 +906,12 @@ public class RuntimeConflictResolver {
         //The hash insert is here because we don't want to enqueue things unless we know it conflicts. 
         currCase.append("        if (" + queryVistedHashtable +"("+ currPtr + ")) {\n");
         
-        //Either it's an in-lineable case or we're just handling primitive conflicts
-        if ((ref.child.getNumOfReachableParents() == 1 && !ref.child.isInsetVar) ||
-            (ref.child.hasPrimitiveConflicts() && !qualifiesForCaseStatement(ref.child)))
-        {
+        if(qualifiesForCaseStatement(ref.child)){
+            currCase.append("        " + addToQueueInC + childPtr + ");\n "); 
+        } else {
           addChecker(taint, ref.child, cases, currCase, currPtr, pDepth + 1);
         }
-        else {
-          //if we are going to insert something into the queue, 
-          //we should be able to resume traverser from it. 
-          assert qualifiesForCaseStatement(ref.child);
-          currCase.append("        " + addToQueueInC + childPtr + ");\n ");
-        }
+        
         currCase.append("    }\n");  //close for queryVistedHashtable
         
         currCase.append("}\n"); //close for internal case statement
@@ -884,6 +945,18 @@ public class RuntimeConflictResolver {
     return null;
   }
   
+  // decide whether the given SESE doesn't have traversers at all
+  public boolean hasEmptyTraversers(FlatSESEEnterNode fsen) {
+    boolean hasEmpty = true;
+
+    Set<FlatSESEEnterNode> children = fsen.getSESEChildren();
+    for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+      FlatSESEEnterNode child = (FlatSESEEnterNode) iterator.next();
+      hasEmpty &= child.getInVarsForDynamicCoarseConflictResolution().size() == 0;
+    }
+    return hasEmpty;
+    
+  }  
   
   private Taint getProperTaintForEnterNode(FlatNode stallSite, VariableNode var,
       Hashtable<Taint, Set<Effect>> effects) {
@@ -913,6 +986,31 @@ public class RuntimeConflictResolver {
         num2WeaklyConnectedHRGroup.add(weaklyConnectedHRCounter, hg);
         weaklyConnectedHRCounter++;
       }
+      
+      if(t.isRBlockTaint()) {
+        int id=connectedHRHash.get(t).id;
+        Tuple tup=new Tuple(t.getVar(),t.getSESE());
+        if (weakMap.containsKey(tup)) {
+          if (weakMap.get(tup).intValue()!=id) 
+            throw new Error("Var/SESE not unique for weak component.");
+        } else 
+            weakMap.put(tup, new Integer(id));
+      }
+    }
+    
+    //output weakly connected groups for verification
+    if(generalDebug) {
+      System.out.println("==============Weakly Connected HeapRoots==============");
+      
+      for(int i=0; i < num2WeaklyConnectedHRGroup.size(); i++){
+        System.out.println("Heap Group #" + i);
+        WeaklyConectedHRGroup hg = num2WeaklyConnectedHRGroup.get(i);
+        for(Taint t: hg.connectedHRs) {
+          System.out.println("\t" + t);
+        }
+      }
+      
+      System.out.println("=======================END LIST=======================");
     }
   }
   
@@ -1205,7 +1303,7 @@ public class RuntimeConflictResolver {
     }
 
     public void addObjChild(String field, ConcreteRuntimeObjNode child, CombinedObjEffects ce) {
-      printDebug(javaDebug,this.allocSite.getUniqueAllocSiteID() + " added child at " + child.getAllocationSite());
+      printDebug(traceDataStructureBuild,this.allocSite.getUniqueAllocSiteID() + " added child at " + child.getAllocationSite());
       hasDirectObjConflict |= ce.hasConflict();
       ObjRef ref = new ObjRef(field, child, ce);
       
@@ -1215,14 +1313,14 @@ public class RuntimeConflictResolver {
         if(array.contains(ref)) {
           ObjRef other = array.get(array.indexOf(ref));
           other.mergeWith(ref);
-          printDebug(javaDebug,"    Merged with old");
-          printDebug(javaDebug,"    Old="+ other.child.original + "\n    new="+ref.child.original);
+          printDebug(traceDataStructureBuild,"    Merged with old");
+          printDebug(traceDataStructureBuild,"    Old="+ other.child.original + "\n    new="+ref.child.original);
         }
         else {
           array.add(ref);
-          printDebug(javaDebug,"    Just added new;\n      Field: " + field);
-          printDebug(javaDebug,"      AllocSite: " + child.getAllocationSite());
-          printDebug(javaDebug,"      Child: "+child.original);
+          printDebug(traceDataStructureBuild,"    Just added new;\n      Field: " + field);
+          printDebug(traceDataStructureBuild,"      AllocSite: " + child.getAllocationSite());
+          printDebug(traceDataStructureBuild,"      Child: "+child.original);
         }
       }
       else {
@@ -1296,7 +1394,7 @@ public class RuntimeConflictResolver {
             bucket = new BucketOfEffects();
             table.put(e.getAffectedAllocSite(), bucket);
           }
-          printDebug(javaDebug, "Added Taint" + t + " Effect " + e + "Conflict Status = " + (localConflicts!=null?localConflicts.contains(e):false)+" localConflicts = "+localConflicts);
+          printDebug(printEffectsAndEffectsTable, "Added Taint" + t + " Effect " + e + "Conflict Status = " + (localConflicts!=null?localConflicts.contains(e):false)+" localConflicts = "+localConflicts);
           bucket.add(t, e, localConflicts!=null?localConflicts.contains(e):false);
         }
       }
@@ -1316,7 +1414,7 @@ public class RuntimeConflictResolver {
     // Run Analysis will walk the data structure and figure out the weakly
     // connected heap roots. 
     public void runAnalysis() {
-      if(javaDebug) {
+      if(printEffectsAndEffectsTable) {
         printoutTable(this); 
       }
       
@@ -1374,8 +1472,10 @@ public class RuntimeConflictResolver {
         Iterator<Taint> it = oldGroup.connectedHRs.iterator();
         Taint relatedTaint;
         
-        while((relatedTaint = it.next()) != null && !connectedHRs.contains(relatedTaint)) {
-          this.add(relatedTaint);
+        while(it.hasNext() && (relatedTaint = it.next()) != null) {
+          if(!connectedHRs.contains(relatedTaint)){
+            this.add(relatedTaint);
+          }
         }
       }
     }