Minor changes: Removing vestigial code
[IRC.git] / Robust / src / IR / Flat / RuntimeConflictResolver.java
index 889f6cae767a7a21cb2be624a80800b2ca40e4c5..e71407d57a6aaa5a629f7d37a717d8f0b084126b 100644 (file)
@@ -185,7 +185,8 @@ public class RuntimeConflictResolver {
    * 5) Print c methods by walking internal representation
    */
   
-  public void addToTraverseToDoList(FlatSESEEnterNode rblock, ReachGraph rg, Hashtable<Taint, Set<Effect>> conflicts) {
+  public void addToTraverseToDoList(FlatSESEEnterNode rblock, ReachGraph rg, 
+      Hashtable<Taint, Set<Effect>> conflicts) {
     //Add to todo list
     toTraverse.add(new TraversalInfo(rblock, rg));
 
@@ -228,8 +229,8 @@ public class RuntimeConflictResolver {
         continue;
       }
       System.out.println(invar);
-      //created stores nodes with specific alloc sites that have been traversed while building
-      //internal data structure. It is later traversed sequentially to find inset variables and
+      //"created" stores nodes with specific alloc sites that have been traversed while building
+      //internal data structure. Created is later traversed sequentially to find inset variables and
       //build output code.
       //NOTE: Integer stores Allocation Site ID in hashtable
       Hashtable<Integer, ConcreteRuntimeObjNode> created = new Hashtable<Integer, ConcreteRuntimeObjNode>();
@@ -469,7 +470,7 @@ public class RuntimeConflictResolver {
       RefEdge edge = possibleEdges.next();
       assert edge != null;
 
-      ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), true, false);
+      ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), true);
       int rootKey = singleRoot.allocSite.getUniqueAllocSiteID();
 
       if (!created.containsKey(rootKey)) {
@@ -507,7 +508,7 @@ public class RuntimeConflictResolver {
           ConcreteRuntimeObjNode child; 
           
           if(isNewChild) {
-            child = new ConcreteRuntimeObjNode(childHRN, false, curr.isObjectArray());
+            child = new ConcreteRuntimeObjNode(childHRN, false);
             created.put(childKey, child);
           } else {
             child = created.get(childKey);
@@ -730,14 +731,14 @@ public class RuntimeConflictResolver {
     boolean objConfRead=false;
     boolean objConfWrite=false;
 
-    //Primitives Test
+    //Direct Primitives Test
     for(String field: node.primitiveConflictingFields.keySet()) {
       CombinedObjEffects effect=node.primitiveConflictingFields.get(field);
       primConfRead|=effect.hasReadConflict;
       primConfWrite|=effect.hasWriteConflict;
     }
 
-    //Object Reference Test
+    //Direct Object Reference Test
     for(String field: node.objectRefs.keySet()) {
       for(ObjRef ref: node.objectRefs.get(field)) {
         CombinedObjEffects effect=ref.myEffects;
@@ -782,54 +783,52 @@ public class RuntimeConflictResolver {
       currCase.append("if (!(tmpvar"+depth+"&READYMASK)) totalcount--;\n");
     }
     
-    int pdepth=depth+1;
-    currCase.append("{\n");
-    //Array Case
-    if(node.isObjectArray() && node.decendantsConflict()) {
-      //since each array element will get its own case statement, we just need to enqueue each item into the queue
-      //note that the ref would be the actual object and node would be of struct ArrayObject
+    //Handle conflicts further down. 
+    if(node.decendantsConflict()) {
+      int pdepth=depth+1;
+      currCase.append("{\n");
       
-      ArrayList<Integer> allocSitesWithProblems = node.getReferencedAllocSites();
-      if(!allocSitesWithProblems.isEmpty()) {
+      //Array Case
+      if(node.isArray() && node.decendantsConflict()) {
         String childPtr = "((struct ___Object___ **)(((char *) &(((struct ArrayObject *)"+ prefix+")->___length___))+sizeof(int)))[i]";
         String currPtr = "arrayElement" + pdepth;
         
-        //This is done with the assumption that an array of object stores pointers. 
         currCase.append("{\n  int i;\n");
+        currCase.append("    struct ___Object___ * "+currPtr+";\n");
         currCase.append("  for(i = 0; i<((struct ArrayObject *) " + prefix + " )->___length___; i++ ) {\n");
-        currCase.append("    struct ___Object___ *"+currPtr+" = "+childPtr+";\n");
-        currCase.append("    if( arrayElement"+pdepth+" != NULL) {\n");
         
         //There should be only one field, hence we only take the first field in the keyset.
         assert node.objectRefs.keySet().size() <= 1;
-        ArrayList<ObjRef> refsAtParticularField = node.objectRefs.get(node.objectRefs.keySet().iterator().next());
+        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
-      for(String field: node.objectRefs.keySet()) {
-        ArrayList<ObjRef> refsAtParticularField = node.objectRefs.get(field);
-        String childPtr = "((struct "+node.original.getType().getSafeSymbol()+" *)"+prefix +")->___" + field + "___";
+        currCase.append("      }}\n");
+      } else {
+      //All other cases
         String currPtr = "myPtr" + pdepth;
-        currCase.append("    struct ___Object___ * "+currPtr+"= (struct ___Object___ * ) " + childPtr + ";\n");
-        currCase.append("    if (" + currPtr + " != NULL) { ");
-        
-        printObjRefSwitchStatement(taint, cases, depth, currCase, refsAtParticularField, childPtr, currPtr);
-        currCase.append("}");
-      }      
+        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. 
     }
-    
-    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,
-      int pDepth, StringBuilder currCase, ArrayList<ObjRef> refsAtParticularField, String childPtr,
+      int pDepth, StringBuilder currCase, ObjRefList refsAtParticularField, String childPtr,
       String currPtr) {
+    
+    currCase.append("    "+currPtr+"= (struct ___Object___ * ) " + childPtr + ";\n");
+    currCase.append("    if (" + currPtr + " != NULL) { \n");
     currCase.append("    switch(" + currPtr + getAllocSiteInC + ") {\n");
     
     for(ObjRef ref: refsAtParticularField) {
@@ -838,10 +837,16 @@ 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");
         
-        if (ref.child.getNumOfReachableParents() == 1 && !ref.child.isInsetVar) {
+        //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)))
+        {
           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
@@ -852,7 +857,7 @@ public class RuntimeConflictResolver {
     
     currCase.append("    default:\n" +
                            "       break;\n"+
-                           "    }\n"); //internal switch. 
+                           "    }}\n"); //internal switch. 
   }
   
   private boolean qualifiesForCaseStatement(ConcreteRuntimeObjNode node) {
@@ -1120,7 +1125,7 @@ public class RuntimeConflictResolver {
   }
 
   private class ConcreteRuntimeObjNode {
-    Hashtable<String, ArrayList<ObjRef>> objectRefs;
+    Hashtable<String, ObjRefList> objectRefs;
     Hashtable<String, CombinedObjEffects> primitiveConflictingFields;
     HashSet<ConcreteRuntimeObjNode> parentsWithReadToNode;
     HashSet<ConcreteRuntimeObjNode> parentsThatWillLeadToConflicts;
@@ -1130,12 +1135,11 @@ public class RuntimeConflictResolver {
     boolean decendantsObjConflict;
     boolean hasPotentialToBeIncorrectDueToConflict;
     boolean isInsetVar;
-    boolean isArrayElement;
     AllocSite allocSite;
     HeapRegionNode original;
 
-    public ConcreteRuntimeObjNode(HeapRegionNode me, boolean isInVar, boolean isArrayElement) {
-      objectRefs = new Hashtable<String, ArrayList<ObjRef>>(5);
+    public ConcreteRuntimeObjNode(HeapRegionNode me, boolean isInVar) {
+      objectRefs = new Hashtable<String, ObjRefList>(5);
       primitiveConflictingFields = null;
       parentsThatWillLeadToConflicts = new HashSet<ConcreteRuntimeObjNode>();
       parentsWithReadToNode = new HashSet<ConcreteRuntimeObjNode>();
@@ -1146,7 +1150,6 @@ public class RuntimeConflictResolver {
       decendantsPrimConflict = false;
       decendantsObjConflict = false;
       hasPotentialToBeIncorrectDueToConflict = false;
-      this.isArrayElement = isArrayElement;
     }
 
     public void addReachableParent(ConcreteRuntimeObjNode curr) {
@@ -1203,7 +1206,7 @@ public class RuntimeConflictResolver {
       ObjRef ref = new ObjRef(field, child, ce);
       
       if(objectRefs.containsKey(field)){
-        ArrayList<ObjRef> array = objectRefs.get(field);
+        ObjRefList array = objectRefs.get(field);
         
         if(array.contains(ref)) {
           ObjRef other = array.get(array.indexOf(ref));
@@ -1219,22 +1222,17 @@ public class RuntimeConflictResolver {
         }
       }
       else {
-        ArrayList<ObjRef> array = new ArrayList<ObjRef>(3);
+        ObjRefList array = new ObjRefList(3);
         
         array.add(ref);
         objectRefs.put(field, array);
       }
     }
     
-    //TODO check that code is functional after removing the primitive and isImutable check
-    public boolean isObjectArray() {
+    public boolean isArray() {
       return original.getType().isArray();
     }
     
-    public boolean canBeArrayElement() {
-      return isArrayElement;
-    }
-    
     public ArrayList<Integer> getReferencedAllocSites() {
       ArrayList<Integer> list = new ArrayList<Integer>();
       
@@ -1256,6 +1254,28 @@ public class RuntimeConflictResolver {
     }
   }
   
+  //Simple extension of the ArrayList to allow it to find if any ObjRefs conflict.
+  private class ObjRefList extends ArrayList<ObjRef> {
+    private static final long serialVersionUID = 326523675530835596L;
+    
+    public ObjRefList(int size) {
+      super(size);
+    }
+    
+    public boolean add(ObjRef o){
+      return super.add(o);
+    }
+    
+    public boolean hasConflicts() {
+      for(ObjRef r: this) {
+        if(r.hasConflictsDownThisPath() || r.child.hasPrimitiveConflicts())
+          return true;
+      }
+      
+      return false;
+    }
+  }
+  
   private class EffectsTable {
     private Hashtable<AllocSite, BucketOfEffects> table;