Unfinished dynamic anaylsis side and probably contains bugs on static anaylsis side
authorstephey <stephey>
Thu, 22 Jul 2010 22:45:51 +0000 (22:45 +0000)
committerstephey <stephey>
Thu, 22 Jul 2010 22:45:51 +0000 (22:45 +0000)
Robust/src/IR/Flat/RuntimeConflictResolver.java [new file with mode: 0644]

diff --git a/Robust/src/IR/Flat/RuntimeConflictResolver.java b/Robust/src/IR/Flat/RuntimeConflictResolver.java
new file mode 100644 (file)
index 0000000..ccf1858
--- /dev/null
@@ -0,0 +1,402 @@
+package IR.Flat;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import Analysis.Disjoint.*;
+
+public class RuntimeConflictResolver {
+       
+       private static final String getAllocSiteInC = "->AllocSite";
+       private static final String queryHashTableInC = "hashtable.contains(";
+       private static final String addToHashTableInC = "hashtable.put(";
+       private static final String addToQueueInC = "queue.enqueue(";
+       private static final String dequeueFromQueueInC = "queue.dequeue()";
+       
+       public void traverse(FlatSESEEnterNode rblock, 
+                       Hashtable<Taint, Set<Effect>> effects,
+                       Hashtable<Taint, Set<Effect>> conflicts,
+                       ReachGraph rg)
+       {
+               Set<TempDescriptor> inVars = rblock.getInVarSet();
+               Hashtable<NodeKey, Node> created = new Hashtable<NodeKey, Node>();
+
+               
+               //Is this even needed?
+               if(inVars.size() == 0)
+                       return;
+               
+               /*
+                * Basic steps:
+                * 1) Create pruned data structures from givens
+                *              1a) Use effects sets to verify if we can access something (reads)
+                *              1b) Mark all conflicts with a special flag (perhaps create wrapper)
+                * 2) Traverse again and build code output structure (as Objects)
+                * 3) printout 
+                */
+               
+               createTree(rblock, inVars, conflicts, rg, created);
+               generateCPrintoutStructure(created);
+               printCCode();
+       }
+
+       //I'll assume that I'll get a pointer to the first data element named ptr
+       private void printHeader(StringBuilder out)
+       {
+               //TODO find out more about Hashset and stuff on the C-side
+               //TODO includes
+               //TODO initialize hashset/hashtable
+               //TODO initialize Queue
+               System.out.println();
+       }
+       private void printFooter(StringBuilder out)
+       {
+               //TODO End the while loops and such 
+               //TODO free stuff we've used???
+       }
+
+       private StringBuilder generateCPrintoutStructure(Hashtable<NodeKey, Node> created) 
+       {
+               HashSet<Integer> done = new HashSet<Integer>();
+               StringBuilder out = new StringBuilder();
+               
+               printHeader(out);
+               for(Node node: created.values())
+               {
+                       //If we haven't seen it and it's a node with more than 1 parent
+                       //Note: a node with 0 parents is a root node (i.e. inset variable)
+                       if(!done.contains(new Integer(node.getAllocationSite())) && node.numOfParents != 1)
+                               addChecker(node, done, out, "ptr");
+               }
+               printFooter(out);
+               
+               return out;
+       }
+       
+       private void addChecker(Node node, 
+                                                       HashSet<Integer> done, 
+                                                       StringBuilder out,
+                                                       String prefix)
+       {
+               if(node.numOfParents != 1) {
+                       assert prefix.equals("ptr");
+                       out.append("case " + node.getAllocationSite() + ":\n");
+               }
+               
+               //adds self to hashtable
+               out.append(addToHashTableInC + prefix + ");");
+               
+               for(Reference ref: node.references)
+               {
+                       String childPtr = prefix + "->" + ref.field;
+                       
+                       //Checks if the child exists and is correct
+                       out.append("if(" + childPtr + " != NULL && " + childPtr + getAllocSiteInC + 
+                                       "==" + ref.allocSite + ") { ");
+                       
+                       //Checks if we have visited the child before
+                       out.append("if(!" + queryHashTableInC + childPtr + ") {");
+                       
+                       if(ref.reference.numOfParents == 1) 
+                               addChecker(ref.reference, done, out, childPtr);
+                       else
+                               out.append(addToQueueInC + childPtr+ "); } ");
+                       
+                       out.append(" }} ");
+               }
+               
+               if(node.numOfParents != 1) 
+                       out.append("break;\n");
+               
+               done.add(new Integer(node.getAllocationSite()));
+       }
+       
+       //I'll assume that I'll be just given a pointer named ptr in my function. 
+       private void printCCode() {
+               // TODO Auto-generated method stub
+               
+       }
+       
+       private void createTree(FlatSESEEnterNode rblock,
+                                                       Set<TempDescriptor> inVars,
+                                                       Hashtable<Taint, Set<Effect>> conflicts, 
+                                                       ReachGraph rg,
+                                                       Hashtable<NodeKey, Node> created) {
+               for(TempDescriptor invar: inVars)
+               {
+                       VariableNode varNode = rg.getVariableNodeNoMutation(invar);
+                       Hashtable<EffectsKey, EffectsHashPair> table = generateHashtable(rblock, varNode ,conflicts, conflicts);
+                       //if table is null that means there's no conflicts, therefore we need not create a traversal
+                       if(table != null)
+                       {
+                               Iterator<RefEdge> possibleRootNodes = varNode.iteratorToReferencees();
+                               
+                               while(possibleRootNodes.hasNext())
+                               {
+                                       RefEdge edge = possibleRootNodes.next();
+                                       assert edge != null;
+
+                                       //always assumed to be a conflict on the root variables. 
+                                       Node singleRoot = new Node(edge.getDst(), true);
+                                       NodeKey rootKey = new NodeKey(singleRoot.allocSite);
+                                       
+                                       if(!created.contains(rootKey)) {
+                                               created.put(rootKey, singleRoot);
+                                               createHelper(singleRoot, edge.getDst().iteratorToReferencees(), created, table);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       /*
+        * Plan is to add stuff to the tree depth-first sort of way. That way, we can propogate up conflicts.
+        */
+       private void createHelper(Node parent, Iterator<RefEdge> edges, Hashtable<NodeKey, Node> created, Hashtable<EffectsKey, EffectsHashPair> table) {
+               assert table != null;
+               while(edges.hasNext()) {
+                       RefEdge edge = edges.next();
+                       String field = edge.getField();
+                       HeapRegionNode childHRN = edge.getDst();
+                       
+                       EffectsKey lookup = new EffectsKey(childHRN.getAllocSite(), field);
+                       EffectsHashPair effect = table.get(lookup);
+                       
+                       //if there's no effect, we don't traverse this edge.
+                       if(effect != null) {
+                               NodeKey key = new NodeKey(childHRN.getAllocSite());
+                               boolean isNewChild = !created.contains(key);
+                               Node child;
+                               
+                               if(isNewChild) 
+                                       child = new Node(childHRN, effect.conflict);
+                               else {
+                                       child = created.get(key);
+                                       child.myConflict = effect.conflict;
+                               }
+                                       
+                               parent.addChild(field, child);                          
+                               if(effect.conflict)
+                                       propogateConflictFlag(parent);
+                               
+                               if(effect.type == Effect.read && isNewChild)
+                                       createHelper(child, childHRN.iteratorToReferencees(), created, table);
+                       }
+               }
+       }
+
+
+       //This will propagate the conflict up the tree. 
+       private void propogateConflictFlag(Node node)
+       {
+               Node curr = node;
+               
+               while(curr != null && curr.decendentsConflict != true)
+               {
+                       curr.decendentsConflict = true;
+                       curr = curr.lastParent;
+               }
+       }
+       
+       
+       
+       
+       private Hashtable<EffectsKey, EffectsHashPair>  generateHashtable(FlatSESEEnterNode rblock, 
+                                                                                                               VariableNode var, 
+                                                                                                               Hashtable<Taint, Set<Effect>> effects,
+                                                                                                               Hashtable<Taint, Set<Effect>> conflicts)
+       {
+               //we search effects since conflicts is only a subset of effects
+               Taint taint = getProperTaint(rblock, var, effects);
+               assert taint !=null;
+               
+               Set<Effect> localEffects = effects.get(taint);
+               Set<Effect> localConflicts = conflicts.get(taint);              
+               
+               if(localEffects == null || localEffects.isEmpty() || conflicts == null || conflicts.isEmpty())
+                       return null;
+               
+               Hashtable<EffectsKey, EffectsHashPair> table = new Hashtable<EffectsKey, EffectsHashPair>();
+               
+               for(Effect e: localEffects)
+               {
+                       EffectsKey key = new EffectsKey(e);
+                       EffectsHashPair element = new EffectsHashPair(e, localConflicts.contains(e));
+                       table.put(key, element);
+               }
+               
+               return table;
+       }
+       
+       private Taint getProperTaint(FlatSESEEnterNode rblock, 
+                                                               VariableNode var, 
+                                                               Hashtable<Taint, Set<Effect>> effects)
+       {
+               Set<Taint> taints = effects.keySet();
+               for(Taint t: taints)
+                       if(t.getSESE().equals(rblock) && t.getVar().equals(var.getTempDescriptor()))
+                               return t;
+               
+               return null;
+       }
+       
+       private class EffectsKey
+       {
+               AllocSite allocsite;
+               String field;
+               
+               public EffectsKey(AllocSite a, String f)
+               {
+                       allocsite = a;
+                       field = f;
+               }
+               
+               public EffectsKey(Effect e)
+               {
+                       allocsite = e.getAffectedAllocSite();
+                       field = e.getField().getSymbol();
+               }
+               
+               //Hashcode only hashes the object based on AllocationSite and Field
+               public int hashCode()
+               {
+                       return allocsite.hashCode() ^ field.hashCode();
+               }
+               
+               //Equals ONLY compares object based on AllocationSite and Field
+               public boolean equals(Object o)
+               {
+                   if (o == null) 
+                       return false;
+
+                   if (!(o instanceof EffectsKey))
+                       return false;
+                   
+                   EffectsKey other = (EffectsKey) o;
+                   
+                   return (other.allocsite.equals(this.allocsite) &&
+                               other.field.equals(this.field));
+               }
+       }
+       
+       private class EffectsHashPair
+       {
+               Effect originalEffect;
+               int type;
+               boolean conflict;
+               
+               public EffectsHashPair(Effect e, boolean conflict)
+               {
+                       originalEffect = e;
+                       type = e.getType();
+                       this.conflict = conflict;
+               }
+               
+               //Hashcode only hashes the object based on AllocationSite and Field
+               public int hashCode()
+               {
+                       return originalEffect.hashCode();
+               }
+               
+               //Equals ONLY compares object based on AllocationSite and Field
+               public boolean equals(Object o)
+               {
+                   if (o == null) 
+                       return false;
+
+                   if (!(o instanceof EffectsHashPair))
+                       return false;
+                   
+                   EffectsHashPair other = (EffectsHashPair) o;
+                   
+                   return (other.originalEffect.getAffectedAllocSite().equals(originalEffect.getAffectedAllocSite()) &&
+                               other.originalEffect.getField().equals(originalEffect.getField()));
+               }
+               
+               public boolean isConflict()
+               {
+                       return conflict;
+               }
+       }
+
+       private class Reference
+       {
+               String field;
+               int allocSite;
+               Node reference;
+               
+               public Reference(String fieldname, Node ref)
+               {
+                       field = fieldname;
+                       allocSite = ref.getAllocationSite();
+                       reference = ref;
+               }
+       }
+       
+       private class NodeKey
+       {
+               int allocsite;
+               
+               public NodeKey(AllocSite site) 
+               {
+                       allocsite = site.hashCodeSpecific();
+               }
+               
+               public int hashCode()
+               {
+                       return allocsite;
+               }
+       }
+       
+
+private class Node
+{
+       ArrayList<Reference> references;
+       Node lastParent;
+       int numOfParents;
+       boolean myConflict;
+       boolean decendentsConflict;
+       AllocSite allocSite;            
+       HeapRegionNode original;
+       
+       public Node(HeapRegionNode me, boolean conflict)
+       {
+               references = new ArrayList<Reference>();
+               lastParent = null;
+               numOfParents = 0;
+               allocSite = me.getAllocSite();
+               original = me;
+               this.myConflict = conflict;
+               decendentsConflict = false;
+       }
+       
+       @Override
+       public int hashCode() 
+       {
+         //I assume this gets the allocsite number number
+         return allocSite.hashCodeSpecific();
+       }
+  
+       @Override
+       public boolean equals(Object obj) 
+       {
+       return original.equals(obj);
+       }
+       
+       public int getAllocationSite()
+       {
+               return allocSite.hashCodeSpecific();
+       }
+       
+       public void addChild(String field, Node child)
+       {
+               child.lastParent = this;
+               child.numOfParents++;
+               Reference ref = new Reference(field, child);
+               references.add(ref);
+       }
+}
+
+}