import IR.Tree.TagExpressionList;
import IR.Tree.OffsetNode;
import IR.*;
+
import java.util.*;
import java.io.*;
import Analysis.Locality.DelayComputation;
import Analysis.Locality.BranchAnalysis;
import Analysis.CallGraph.CallGraph;
+import Analysis.Disjoint.AllocSite;
import Analysis.Disjoint.Effect;
import Analysis.Disjoint.ReachGraph;
import Analysis.Disjoint.Taint;
"sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
"perror(errmsg); exit(-1); }";
boolean nonSESEpass=true;
+ RuntimeConflictResolver rcr = null;
WriteBarrier wb;
DiscoverConflicts dc;
DiscoverConflicts recorddc;
// Output the C class declarations
// These could mutually reference each other
+
+
+ outclassdefs.println("#ifndef __CLASSDEF_H_");
+ outclassdefs.println("#define __CLASSDEF_H_");
outputClassDeclarations(outclassdefs);
// Output function prototypes and structures for parameters
ClassDescriptor cn=(ClassDescriptor)it.next();
generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
}
+ outclassdefs.println("#endif");
outclassdefs.close();
if (state.TASK) {
}else{
seseit=oooa.getAllSESEs().iterator();
}
+
+ //TODO signal the object that will report errors
+ if(state.RCR) {
+ try {
+ rcr = new RuntimeConflictResolver(PREFIX);
+ }
+ catch (FileNotFoundException e) {
+ System.out.println("Runtime Conflict Resolver could not create output file.");
+ }
+ }
+
while(seseit.hasNext()){
FlatSESEEnterNode fsen = seseit.next();
initializeSESE( fsen );
- /*
- if(state.RCR){
- if(!fsen.getIsCallerSESEplaceholder() && fsen.getParent()!=null){
-
- FlatMethod fm=fsen.getfmEnclosing();
-
- //reach graph
- ReachGraph rg=oooa.getDisjointAnalysis().getReachGraph(fm.getMethod());
-
- //get effect set
- Hashtable<Taint, Set<Effect>> effects=oooa.getDisjointAnalysis().getEffectsAnalysis().get(fsen);
-
- //get conflict set
- Analysis.OoOJava.ConflictGraph conflictGraph=oooa.getConflictGraph(fsen.getParent());
- Hashtable<Taint, Set<Effect>> conflicts=conflictGraph.getConflictEffectSet(fsen);
+ if(state.RCR && rcr != null){
+ Analysis.OoOJava.ConflictGraph conflictGraph;
+ Hashtable<Taint, Set<Effect>> conflicts;
+ if(!fsen.getIsCallerSESEplaceholder() && fsen.getParent()!=null &&
+ (conflictGraph = oooa.getConflictGraph(fsen.getParent())) != null &&
+ (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null){
+
+ FlatMethod fm=fsen.getfmEnclosing();
+
+ //reach graph
+ ReachGraph rg=oooa.getDisjointAnalysis().getReachGraph(fm.getMethod());
+
+ //TODO remove this later
+ rg.writeGraph("RCRDEBUG");
+
+ //get effect set
+ Hashtable<Taint, Set<Effect>> effects=oooa.getDisjointAnalysis().getEffectsAnalysis().get(fsen);
+
+ rcr.traverse(fsen, effects, conflicts, rg);
+ }
}
}
- */
- }
+ if(rcr != null) {
+ rcr.close();
+ System.out.println("Runtime Conflict Resolver Done.");
+ }
}
/* Build the actual methods */
outmethod.println("#include <stdio.h>");
outmethod.println("#include \"mlp_runtime.h\"");
outmethod.println("#include \"psemaphore.h\"");
+
+ if( state.RCR) {
+ outmethod.println("#include \"RuntimeConflictResolver.h\"");
+ }
}
if (state.COREPROF) {
outmethod.println("#include \"coreprof.h\"");
WaitingElement waitingElement = (WaitingElement) iterator.next();
if( waitingElement.getStatus() >= ConflictNode.COARSE ){
+ // HERE! a parent might conflict with a child
output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller);");
}else{
output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseCaller, (void*)&___locals___."+ waitingElement.getDynID() + ");");
+ "],rentry)==NOTREADY){");
output.println(" ++(localCount);");
output.println(" }");
+
+ // Trying to execute the dynamic coarse grain conflict strategy...
+ if(state.RCR && rcr != null) {
+ boolean useParentContext = false;
+
+ if( (state.MLP &&fsen != mlpa.getMainSESE()) ||
+ (state.OOOJAVA &&fsen != oooa.getMainSESE())) {
+ assert fsen.getParent() != null;
+ if( !fsen.getParent().getIsCallerSESEplaceholder() ) {
+ useParentContext = true;
+ }
+ }
+
+ //TODO fix this workaround later by invoking it only once in the lifetime of the program
+ output.println(" initializeStructsRCR();");
+
+ for (TempDescriptor invar : fsen.getInVarsForDynamicCoarseConflictResolution()) {
+ String varString;
+ if( useParentContext ) {
+ varString = generateTemp( fsen.getParent().getfmBogus(), invar, null );
+ } else {
+ varString = generateTemp( fsen.getfmEnclosing(), invar, null );
+ }
+ output.println(" "+rcr.getTraverserInvocation(invar, varString, fsen));
+ }
+ }
}else{
output
.println(" ADDRENTRYTOBUF(parentCommon->memoryQueueArray["
import java.util.Iterator;
import java.util.Set;
import Analysis.Disjoint.*;
+import IR.TypeDescriptor;
+//TODO fix inaccuracy problem and take advantage of the refEdges
//TODO make it so that methods with no conflicts get no output.
//TODO Make more efficient by only using ONE hashtable.
if (inVars.size() == 0)
return;
- // For every inVariable, generate unique method
+ // For every non-primative variable, generate unique method
+ // Special Note: The Criteria for executing printCMethod in this loop should match
+ // exactly the criteria in buildcode.java to invoke the generated C method(s).
for (TempDescriptor invar : inVars) {
+ TypeDescriptor type = invar.getType();
+ if(type == null || type.isPrimitive()) {
+ continue;
+ }
+
Hashtable<AllocSite, ConcreteRuntimeObjNode> created = new Hashtable<AllocSite, ConcreteRuntimeObjNode>();
createTree(rblock, invar, effects, conflicts, rg, created);
if (!created.isEmpty()) {
- printCMethod(created, invar.getSymbol(), rblock.getSESErecordName());
+ rblock.addInVarForDynamicCoarseConflictResolution(invar);
+ printCMethod(created, invar.getSafeSymbol(), rblock.getPrettyIdentifier());
}
}
}
RefEdge edge = possibleEdges.next();
assert edge != null;
- // always assumed to be a conflict on the root variables.
- ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), true, true);
+ ConcreteRuntimeObjNode singleRoot = new ConcreteRuntimeObjNode(edge.getDst(), false, true);
AllocSite rootKey = singleRoot.allocSite;
if (!created.containsKey(rootKey)) {
}
}
+ private Hashtable<AllocSite, EffectsGroup> generateEffectsLookupTable(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() || localConflicts == null || localConflicts.isEmpty())
+ return null;
+
+ // Debug Code for manually checking effects
+ // System.out.println("For Taint " + taint);
+ // System.out.println("Effects");
+ // for(Effect e: localEffects)
+ // {
+ // System.out.println(e);
+ // }
+ //
+ // System.out.println("Conflicts");
+ // for(Effect e: localConflicts)
+ // {
+ // System.out.println(e);
+ // }
+
+ Hashtable<AllocSite, EffectsGroup> lookupTable = new Hashtable<AllocSite, EffectsGroup>();
+
+ for (Effect e : localEffects) {
+ boolean conflict = localConflicts.contains(e);
+ AllocSite key = e.getAffectedAllocSite();
+ EffectsGroup myEffects = lookupTable.get(key);
+
+ if(myEffects == null) {
+ myEffects = new EffectsGroup();
+ lookupTable.put(key, myEffects);
+ }
+
+ if(e.getField().getType().isPrimitive()) {
+ if(conflict) {
+ myEffects.addPrimative(e);
+ }
+ }
+ else {
+ myEffects.addObj(e, conflict);
+ }
+ }
+
+ return lookupTable;
+ }
+
// Plan is to add stuff to the tree depth-first sort of way. That way, we can
// propagate up conflicts
private void createHelper(ConcreteRuntimeObjNode curr, Iterator<RefEdge> edges, Hashtable<AllocSite, ConcreteRuntimeObjNode> created,
Hashtable<AllocSite, EffectsGroup> table) {
assert table != null;
-
AllocSite parentKey = curr.allocSite;
EffectsGroup currEffects = table.get(parentKey);
}
else {
child = created.get(childKey);
- child.myObjConflict = effect.conflict || child.myObjConflict;
}
- curr.addObjChild(field, child);
+ curr.addObjChild(field, child, effect.conflict);
if (effect.conflict) {
propogateObjConflictFlag(child);
}
}
- private Hashtable<AllocSite, EffectsGroup> generateEffectsLookupTable(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() || localConflicts == null || localConflicts.isEmpty())
- return null;
-
-// Debug Code for manually checking effects
-// System.out.println("For Taint " + taint);
-// System.out.println("Effects");
-// for(Effect e: localEffects)
-// {
-// System.out.println(e);
-// }
-//
-// System.out.println("Conflicts");
-// for(Effect e: localConflicts)
-// {
-// System.out.println(e);
-// }
-
- Hashtable<AllocSite, EffectsGroup> lookupTable = new Hashtable<AllocSite, EffectsGroup>();
-
- for (Effect e : localEffects) {
- boolean conflict = localConflicts.contains(e);
- AllocSite key = e.getAffectedAllocSite();
- EffectsGroup myEffects = lookupTable.get(key);
-
- if(myEffects == null) {
- myEffects = new EffectsGroup();
- lookupTable.put(key, myEffects);
- }
-
- if(e.getField().getType().isPrimitive()) {
- if(conflict) {
- myEffects.addPrimative(e);
- }
- }
- else {
- myEffects.addObj(e, conflict);
- }
- }
-
- return lookupTable;
- }
-
// This will propagate the conflict up the data structure.
private void propogateObjConflictFlag(ConcreteRuntimeObjNode in) {
ConcreteRuntimeObjNode node = in;
// note that primitive in-set variables do not generate effects, so we can assume
// that inVar is an object
+ //Note: remember to change getTraverserInvocation if you change the line below
String methodName = "void traverse___" + inVar.replaceAll(" ", "") + rBlock.replaceAll(" ", "") +
"___(void * InVar)";
cFile.append(methodName + " {\n");
headerFile.append(methodName + ";\n");
+ cFile.append("printf(\"The traverser ran for " + methodName + "\\n\");\n");
+
//Casts the ptr to a genericObjectSTruct so we can get to the ptr->allocsite field.
cFile.append("struct genericObjectStruct * ptr = (struct genericObjectStruct *) InVar; if(InVar != NULL) { " + queryAndAddHashTableInC
+ "ptr); do { ");
cFile.flush();
}
+
+ public String getTraverserInvocation(TempDescriptor invar, String varString, FlatSESEEnterNode sese) {
+ return "traverse___" + invar.getSafeSymbol().replaceAll(" ", "") +
+ sese.getPrettyIdentifier().replaceAll(" ", "") + "___("+varString+");";
+ }
/*
* addChecker creates a case statement for every object that is either an inset variable
//Specific Primitives test for invars
if(node.isInsetVar && node.hasPrimativeConflicts())
- handlePrimitiveConflict(prefix, node.primativeFields);
+ handlePrimitiveConflict(prefix, node.primativeFields, node.allocSite);
// TODO orientation
//Casts C pointer; depth is used to create unique "myPtr" name
+ ref.allocSite + ") { ");
// Prints out conflicts of child
- if (ref.child.myObjConflict)
+ if (ref.conflict)
handleObjConflict(childPtr, node.allocSite);
if(ref.child.hasPrimativeConflicts())
- handlePrimitiveConflict(childPtr, ref.child.primativeFields);
+ handlePrimitiveConflict(childPtr, ref.child.primativeFields, ref.child.allocSite);
if (ref.child.decendantsConflict()) {
// Checks if we have visited the child before
cFile.append("printf(\"Conflict detected with %p from parent with allocation site %u\\n\"," + childPtr + "," + allocSite.hashCodeSpecific() + ");");
}
- private void handlePrimitiveConflict(String ptr, ArrayList<String> conflicts) {
- cFile.append("printf(\"Primitive Conflict detected with %p\\n\", "+ptr+"); ");
+ private void handlePrimitiveConflict(String ptr, ArrayList<String> conflicts, AllocSite allocSite) {
+ cFile.append("printf(\"Primitive Conflict detected with %p with alloc site %u\\n\", "+ptr+", "+allocSite.hashCodeSpecific()+"); ");
}
private Taint getProperTaint(FlatSESEEnterNode rblock, VariableNode var,
private class ObjRef {
String field;
int allocSite;
+ boolean conflict;
ConcreteRuntimeObjNode child;
- public ObjRef(String fieldname, ConcreteRuntimeObjNode ref) {
+ public ObjRef(String fieldname, ConcreteRuntimeObjNode ref, boolean con) {
field = fieldname;
allocSite = ref.getAllocationSite();
child = ref;
+ conflict = con;
}
}
ArrayList<ConcreteRuntimeObjNode> parents;
HashSet<ConcreteRuntimeObjNode> conflictingParents;
ConcreteRuntimeObjNode lastReferencer;
- boolean myObjConflict;
boolean decendantsPrimConflict;
boolean decendantsObjConflict;
boolean isInsetVar;
lastReferencer = null;
allocSite = me.getAllocSite();
original = me;
- myObjConflict = conflict;
isInsetVar = isInVar;
decendantsPrimConflict = false;
decendantsObjConflict = false;
}
public boolean hasConflicts() {
- return (primativeFields != null) || myObjConflict;
+ return (primativeFields != null) || !conflictingParents.isEmpty();
}
public boolean decendantsConflict() {
return decendantsPrimConflict || decendantsObjConflict;
}
- public void addObjChild(String field, ConcreteRuntimeObjNode child) {
+ public void addObjChild(String field, ConcreteRuntimeObjNode child, boolean conflict) {
child.lastReferencer = this;
- ObjRef ref = new ObjRef(field, child);
+ ObjRef ref = new ObjRef(field, child, conflict);
objectRefs.add(ref);
child.parents.add(this);
}
public String toString()
{
- return "AllocSite=" + getAllocationSite() + " myConflict=" + myObjConflict +
+ return "AllocSite=" + getAllocationSite() + " myConflict=" + !conflictingParents.isEmpty() +
" decCon="+decendantsObjConflict+ " NumOfParents=" + parents.size()+
" NumOfConParents=" + getNumOfReachableParents() + " ObjectChildren=" + objectRefs.size();
}