From: jjenista Date: Sat, 19 Mar 2011 01:21:49 +0000 (+0000) Subject: we took DFJ and broke its arm, and we'll reset the bones in an upcoming patch X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4ea437e991a0618a7f834228bfce35e59b87a52b;p=IRC.git we took DFJ and broke its arm, and we'll reset the bones in an upcoming patch --- diff --git a/Robust/src/Analysis/Disjoint/BuildStateMachines.java b/Robust/src/Analysis/Disjoint/BuildStateMachines.java index bed70eec..966555de 100644 --- a/Robust/src/Analysis/Disjoint/BuildStateMachines.java +++ b/Robust/src/Analysis/Disjoint/BuildStateMachines.java @@ -6,6 +6,7 @@ import java.io.*; import IR.*; import IR.Flat.*; import Analysis.OoOJava.*; +import Util.*; ////////////////////////////////////////////// @@ -27,15 +28,22 @@ public class BuildStateMachines { protected Hashtable< FlatNode, Hashtable > fn2var2smfe; + + // remember all the FlatNode/TempDescriptor pairs that have a state machines + // for easy retrieval of all machines + protected Set allMachineNamePairs; + public BuildStateMachines() { fn2var2smfe = new Hashtable< FlatNode, Hashtable >(); + + allMachineNamePairs = new HashSet(); } - protected StateMachineForEffects getStateMachine( FlatNode fn, - TempDescriptor var ) { + public StateMachineForEffects getStateMachine( FlatNode fn, + TempDescriptor var ) { Hashtable var2smfe = fn2var2smfe.get( fn ); if( var2smfe == null ) { @@ -47,12 +55,19 @@ public class BuildStateMachines { if( smfe == null ) { smfe = new StateMachineForEffects( fn ); var2smfe.put( var, smfe ); + + allMachineNamePairs.add( new Pair( fn, var ) ); } return smfe; } + public Set getAllMachineNames() { + return allMachineNamePairs; + } + + public void addToStateMachine( Taint t, Effect e, FlatNode currentProgramPoint ) { diff --git a/Robust/src/Analysis/Disjoint/SMFEState.java b/Robust/src/Analysis/Disjoint/SMFEState.java index de37a165..3374def8 100644 --- a/Robust/src/Analysis/Disjoint/SMFEState.java +++ b/Robust/src/Analysis/Disjoint/SMFEState.java @@ -20,8 +20,20 @@ import IR.Flat.*; public class SMFEState { - // uniquely identifies this state - protected FlatNode id; + // ##################### + // ## NOTE NOTE NOTE!!!! + // ##################### + // When every state corresponds to exactly one + // FlatNode (whereDefined attribute) then we can + // use the FlatNode's id as an ID. BUT BUT BUT, if + // we merge nodes together in the future for + // optimizations and whatnot, we need an alternate + // system of unique IDs + + // uniquely identifies this state + protected int id; + protected int iHashCode; + // all possible effects in this state protected Set effects; @@ -30,29 +42,20 @@ public class SMFEState { // set of new states protected Hashtable< Effect, Set > e2states; + // useful for knowing when a state can be inlined during + // code gen + protected int refCount; - // once you get your hands on an SMFEState in the - // RuntimeConflictResolver side of things, this is how you - // find out what effects are possible in this state - public Set getEffectsAllowed() { - return effects; - } - - // some subset of the above effects may transition to - // other states - public Set transitionsTo( Effect e ) { - Set statesOut = e2states.get( e ); - if( statesOut == null ) { - statesOut = new HashSet(); - } - return statesOut; - } - public SMFEState( FlatNode id ) { - this.id = id; + public SMFEState( FlatNode fnWhereDefined ) { + + this.id = fnWhereDefined.nodeid; + this.iHashCode = fnWhereDefined.hashCode(); + effects = new HashSet(); e2states = new Hashtable< Effect, Set >(); + refCount = 0; } public void addEffect( Effect e ) { @@ -70,13 +73,36 @@ public class SMFEState { e2states.put( effect, states ); } states.add( stateTo ); + + ++stateTo.refCount; } - public FlatNode getID() { + public int getID() { return id; } + // once you get your hands on an SMFEState in the + // RuntimeConflictResolver side of things, this is how you + // find out what effects are possible in this state + public Set getEffectsAllowed() { + return effects; + } + + // some subset of the above effects may transition to + // other states + public Set transitionsTo( Effect e ) { + Set statesOut = e2states.get( e ); + if( statesOut == null ) { + statesOut = new HashSet(); + } + return statesOut; + } + + public int getRefCount() { + return refCount; + } + public boolean equals( Object o ) { if( o == null ) { @@ -89,19 +115,18 @@ public class SMFEState { SMFEState state = (SMFEState) o; - return id.equals( state.id ); + return id == state.id; } public int hashCode() { - return id.hashCode(); + return iHashCode; } public String toStringDOT() { // first create the state as a node in DOT graph - String s = " "+id.nodeid+ - "[shape=box,label=\""; + String s = " "+id+"[shape=box,label=\""; if( effects.size() == 1 ) { s += effects.iterator().next().toString(); @@ -132,11 +157,12 @@ public class SMFEState { SMFEState state = sItr.next(); s += "\n "+ - id.nodeid+" -> "+state.id.nodeid+ + id+" -> "+state.id+ "[label=\""+e+"\"];"; } } return s; } + } diff --git a/Robust/src/Analysis/Disjoint/StateMachineForEffects.java b/Robust/src/Analysis/Disjoint/StateMachineForEffects.java index f12aa2d6..45e3212f 100644 --- a/Robust/src/Analysis/Disjoint/StateMachineForEffects.java +++ b/Robust/src/Analysis/Disjoint/StateMachineForEffects.java @@ -48,7 +48,7 @@ public class StateMachineForEffects { stateFrom.addTransition( e, stateTo ); } - public SMFEState getIntialState() { + public SMFEState getInitialState() { return initialState; } diff --git a/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java b/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java index 8f1e9b79..8ea2f51b 100644 --- a/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java +++ b/Robust/src/Analysis/OoOJava/OoOJavaAnalysis.java @@ -88,6 +88,10 @@ public class OoOJavaAnalysis { return disjointAnalysisTaints; } + public BuildStateMachines getBuildStateMachines() { + return buildStateMachines; + } + public OoOJavaAnalysis( State state, TypeUtil typeUtil, CallGraph callGraph, @@ -1268,13 +1272,16 @@ public class OoOJavaAnalysis { } - // the traversal for pruning state machines and finding // machines that are weakly connected BOTH consider conflicting // effects between heap roots, so it is smart to compute all of // this together public void pruneMachinesAndFindWeaklyConnectedExaminers() { + /* + // TODO, calcualte the set of taints that lead to conflicts (for which + // traversers must be built...) + EffectsAnalysis effectsAnalysis = disjointAnalysisTaints.getEffectsAnalysis(); // visit every conflict graph once, so iterate through the @@ -1294,15 +1301,10 @@ public class OoOJavaAnalysis { // and use them to identify (1) weakly connected heap examiners and // (2) states/examiner nodes with a conflicting effect that will later // support the examiner pruning process - Set conflictEdges = conflictGraph.getEdgeSet(); - for( Iterator edgeItr = conflictEdges.iterator(); edgeItr.hasNext(); ) { - ConflictEdge conflictEdge = (ConflictEdge) edgeItr.next(); - - - } + Hashtable> conflicts = conflictGraph.getConflictEffectSet( fsen ) ); } - + */ } diff --git a/Robust/src/IR/Flat/BuildOoOJavaCode.java b/Robust/src/IR/Flat/BuildOoOJavaCode.java index 12807e31..757b12f0 100644 --- a/Robust/src/IR/Flat/BuildOoOJavaCode.java +++ b/Robust/src/IR/Flat/BuildOoOJavaCode.java @@ -72,8 +72,7 @@ public class BuildOoOJavaCode extends BuildCode { if( state.RCR ) { try { rcr = new RuntimeConflictResolver( PREFIX, - oooa, - oooa.getDisjointAnalysis().getEffectsAnalysis().getAllEffects(), + oooa, state ); System.out.println("Runtime Conflict Resolver started."); } catch (FileNotFoundException e) { diff --git a/Robust/src/IR/Flat/RuntimeConflictResolver.java b/Robust/src/IR/Flat/RuntimeConflictResolver.java index ba6d5dfb..9a893fc3 100644 --- a/Robust/src/IR/Flat/RuntimeConflictResolver.java +++ b/Robust/src/IR/Flat/RuntimeConflictResolver.java @@ -44,23 +44,23 @@ public class RuntimeConflictResolver { //This keeps track of taints we've traversed to prevent printing duplicate traverse functions //The Integer keeps track of the weakly connected group it's in (used in enumerateHeapRoots) - private Hashtable doneTaints; - private Hashtable idMap=new Hashtable(); - private Hashtable weakMap=new Hashtable(); - private Hashtable> globalEffects; - private Hashtable> globalConflicts; + //private Hashtable doneTaints; + //private Hashtable idMap=new Hashtable(); + //private Hashtable weakMap=new Hashtable(); + //private Hashtable> globalEffects; + //private Hashtable> globalConflicts; - private ArrayList traverserTODO; + //private ArrayList traverserTODO; // Hashtable provides fast access to heaproot # lookups - private Hashtable connectedHRHash; - private ArrayList num2WeaklyConnectedHRGroup; - private int traverserIDCounter; - public int currentID=1; + //private Hashtable connectedHRHash; + //private ArrayList num2WeaklyConnectedHRGroup; + //private int traverserIDCounter; + //public int currentID=1; private int weaklyConnectedHRCounter; - private ArrayList pendingPrintout; - private EffectsTable effectsLookupTable; - private OoOJavaAnalysis oooa; + //private ArrayList pendingPrintout; + //private EffectsTable effectsLookupTable; + private OoOJavaAnalysis oooa; private State state; // initializing variables can be found in printHeader() @@ -85,29 +85,27 @@ public class RuntimeConflictResolver { * 4) Build internal representation of the rgs (pruned) * 5) Print c methods by walking internal representation */ - public RuntimeConflictResolver(String buildir, OoOJavaAnalysis oooa, Hashtable> globalEffects, State state) + public RuntimeConflictResolver( String buildir, + OoOJavaAnalysis oooa, + State state) throws FileNotFoundException { this.oooa=oooa; this.state=state; this.generalDebug = state.RCR_DEBUG || state.RCR_DEBUG_VERBOSE; this.verboseDebug = state.RCR_DEBUG_VERBOSE; - doneTaints = new Hashtable(); - connectedHRHash = new Hashtable(); - pendingPrintout = new ArrayList(); - traverserTODO = new ArrayList(); - globalConflicts = new Hashtable>(); - //Note: globalEffects is not instantiated since it'll be passed in whole while conflicts comes in chunks + //doneTaints = new Hashtable(); + //connectedHRHash = new Hashtable(); + //pendingPrintout = new ArrayList(); + //traverserTODO = new ArrayList(); - traverserIDCounter = 1; - weaklyConnectedHRCounter = 0; + //traverserIDCounter = 1; + weaklyConnectedHRCounter = 1; //note: the order below MATTERS setupOutputFiles(buildir); - setGlobalEffects(globalEffects); - getAllTasksAndConflicts(); - buildEffectsLookupStructure(); - createInternalGraphs(); + //getAllTasksAndConflicts(); + //createInternalGraphs(); //After the internal graphs are created, we can print, //but printing is done in close(); } @@ -128,207 +126,8 @@ public class RuntimeConflictResolver { headerFile.println("#define __3_RCR_H_"); } - private void setGlobalEffects(Hashtable> effects) { - globalEffects = effects; - - if(verboseDebug) { - System.out.println("============EFFECTS LIST AS PASSED IN============"); - for(Taint t: globalEffects.keySet()) { - System.out.println("For Taint " + t); - for(Effect e: globalEffects.get(t)) { - System.out.println("\t" + e); - } - } - System.out.println("====================END LIST===================="); - } - } - private void getAllTasksAndConflicts() { - FlatSESEEnterNode fsen; - FlatSESEEnterNode parentSESE; - ConflictGraph conflictGraph; - ReachGraph rg; - Graph g; - Hashtable> conflicts; - HeapAnalysis heapAnalysis = oooa.getDisjointAnalysis(); - - //Go through the SESE's - printDebug(generalDebug, "======================SESE's======================"); - if (heapAnalysis instanceof DisjointAnalysis) { - DisjointAnalysis disjointAnalysis=(DisjointAnalysis) heapAnalysis; - for(Iterator seseit = oooa.getAllSESEs().iterator();seseit.hasNext();) { - fsen = seseit.next(); - - if ( fsen.getParents().size() > 0 && - (parentSESE = (FlatSESEEnterNode) fsen.getParents().iterator().next()) != null && - (conflictGraph = oooa.getConflictGraph(parentSESE)) != null && - (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null && - (rg = disjointAnalysis.getEnterReachGraph(fsen)) != null ){ - - addToTraverseToDoList(fsen, rg, conflicts, conflictGraph); - } - } - } else { - Pointer pointerAnalysis=(Pointer) heapAnalysis; - for(Iterator seseit = oooa.getAllSESEs().iterator();seseit.hasNext();) { - fsen = seseit.next(); - - if ( fsen.getParents().size() > 0 && - (parentSESE = (FlatSESEEnterNode) fsen.getParents().iterator().next()) != null && - (conflictGraph = oooa.getConflictGraph(parentSESE)) != null && - (conflicts = conflictGraph.getConflictEffectSet(fsen)) != null && - (g = pointerAnalysis.getGraph(fsen)) != null ){ - addToTraverseToDoList(fsen, g, conflicts, conflictGraph); - } - } - } - - printDebug(generalDebug, "==================END SESE LIST=================="); - - if (heapAnalysis instanceof DisjointAnalysis) { - DisjointAnalysis disjointAnalysis=(DisjointAnalysis) heapAnalysis; - - // Go through the stall sites - for(Iterator codeit = oooa.getNodesWithPlans().iterator();codeit.hasNext();){ - FlatNode fn = codeit.next(); - CodePlan cp = oooa.getCodePlan(fn); - fsen = cp.getCurrentSESE(); - - if(fsen.getParents().size() != 0 && - (conflictGraph = oooa.getConflictGraph(fsen)) != null && - (conflicts = conflictGraph.getConflictEffectSet(fn)) != null && - (rg = disjointAnalysis.getEnterReachGraph(fn)) != null) { - Set seseLockSet = oooa.getLockMappings(conflictGraph); - Set waitingElementSet = - conflictGraph.getStallSiteWaitingElementSet(fn, seseLockSet); - - if (waitingElementSet.size() > 0) { - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - - WaitingElement waitingElement = (WaitingElement) iterator.next(); - addToTraverseToDoList(fn, waitingElement.getTempDesc(), rg, conflicts); - } - } - } - } - } else { - Pointer pointerAnalysis=(Pointer) heapAnalysis; - // Go through the stall sites - for(Iterator codeit = oooa.getNodesWithPlans().iterator();codeit.hasNext();){ - FlatNode fn = codeit.next(); - CodePlan cp = oooa.getCodePlan(fn); - fsen = cp.getCurrentSESE(); - - if(fsen.getParents().size() != 0 && - (conflictGraph = oooa.getConflictGraph(fsen)) != null && - (conflicts = conflictGraph.getConflictEffectSet(fn)) != null && - (g = pointerAnalysis.getGraph(fn)) != null) { - Set seseLockSet = oooa.getLockMappings(conflictGraph); - Set waitingElementSet = - conflictGraph.getStallSiteWaitingElementSet(fn, seseLockSet); - - if (waitingElementSet.size() > 0) { - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - - WaitingElement waitingElement = (WaitingElement) iterator.next(); - addToTraverseToDoList(fn, waitingElement.getTempDesc(), g, conflicts); - } - } - } - } - } - } - - public void addToTraverseToDoList(FlatSESEEnterNode rblock, - ReachGraph rg, - Hashtable> conflicts, - ConflictGraph conflictGraph) { - - traverserTODO.add(new TraversalInfo(rblock, rg)); - addToGlobalConflicts(conflicts); - - if(generalDebug) { - System.out.println(rblock); - System.out.println(rblock.getParents()); - System.out.println("CG=" + conflictGraph); - if(verboseDebug) - rg.writeGraph("RCR_RG_SESE_DEBUG"+removeInvalidChars(rblock.getPrettyIdentifier())); - } - } - - public void addToTraverseToDoList(FlatNode fn, - TempDescriptor tempDesc, - ReachGraph rg, - Hashtable> conflicts) - { - traverserTODO.add(new TraversalInfo(fn, rg, tempDesc)); - addToGlobalConflicts(conflicts); - - if (verboseDebug) - rg.writeGraph("RCR_RG_STALLSITE_DEBUG"+removeInvalidChars(fn.toString())); - } - - public void addToTraverseToDoList(FlatSESEEnterNode rblock, - Graph rg, - Hashtable> conflicts, - ConflictGraph conflictGraph) { - - traverserTODO.add(new TraversalInfo(rblock, rg)); - addToGlobalConflicts(conflicts); - - if(generalDebug) { - System.out.println(rblock); - System.out.println(rblock.getParents()); - System.out.println("CG=" + conflictGraph); - } - } - - public void addToTraverseToDoList(FlatNode fn, - TempDescriptor tempDesc, - Graph rg, - Hashtable> conflicts) { - traverserTODO.add(new TraversalInfo(fn, rg, tempDesc)); - addToGlobalConflicts(conflicts); - } - - private void addToGlobalConflicts(Hashtable> conflicts) { - for(Taint t: conflicts.keySet()) { - if(globalConflicts.containsKey(t)) { - globalConflicts.get(t).addAll(conflicts.get(t)); - } else { - globalConflicts.put(t, conflicts.get(t)); - } - } - } - - //Builds Effects Table and runs the analysis on them to get weakly connected HRs - //SPECIAL NOTE: Only runs after we've taken all the conflicts and effects (via getAllTasksAndConflicts) - private void buildEffectsLookupStructure(){ - effectsLookupTable = new EffectsTable(globalEffects, globalConflicts); - effectsLookupTable.runAnalysis(); - enumerateHeaproots(); - } - - private void createInternalGraphs() { - for(TraversalInfo t: traverserTODO) { - printDebug(generalDebug, "Running Traversal on " + t.f); - - //Runs stallsite graph creation - if(t.isStallSite()) { - assert t.invar != null; - createTraversalGraph(t.f, t.invar, t.rg); - } - //runs rblock graph creation - else { - FlatSESEEnterNode rblock = (FlatSESEEnterNode)t.f; - - for (TempDescriptor invar : rblock.getInVarSet()) { - createTraversalGraph(rblock, invar, t.rg); - } - } - } - } - + /* //This method creates an pruned version of the reach graph using effects //The graph ultimately steers the the runtime traverser and is used to generate output code private void createTraversalGraph(FlatNode fn, TempDescriptor invar, ReachGraph rg) { @@ -473,7 +272,8 @@ public class RuntimeConflictResolver { } } } - + */ + //This extends a tempDescriptor's isPrimitive test by also excluding primitive arrays. private boolean isReallyAPrimitive(TypeDescriptor type) { return (type.isPrimitive() && !type.isArray()); @@ -508,25 +308,38 @@ public class RuntimeConflictResolver { return s.toString(); } + // TODO, THIS WORKS A NEW WAY public int getWeakID(TempDescriptor invar, FlatNode fn) { - return weakMap.get(new Pair(invar, fn)).intValue(); + //return weakMap.get(new Pair(invar, fn)).intValue(); + return -12; } - public int getTraverserID(TempDescriptor invar, FlatNode fn) { - Pair t=new Pair(invar, fn); - if (idMap.containsKey(t)) - return idMap.get(t).intValue(); - int value=currentID++; - idMap.put(t, new Integer(value)); - return value; + //Pair t=new Pair(invar, fn); + //if (idMap.containsKey(t)) + // return idMap.get(t).intValue(); + //int value=currentID++; + //idMap.put(t, new Integer(value)); + //return value; + return -12; } + public void close() { - //prints the traversal code - for(TaintAndInternalHeapStructure ths: pendingPrintout) { - printCMethod(ths.nodesInHeap, ths.t); + + BuildStateMachines bsm = oooa.getBuildStateMachines(); + + for( Pair p: bsm.getAllMachineNames() ) { + FlatNode taskOrStallSite = (FlatNode) p.getFirst(); + TempDescriptor var = (TempDescriptor) p.getSecond(); + + //prints the traversal code + printCMethod( taskOrStallSite, + var, + bsm.getStateMachine( taskOrStallSite, var ), + 0 ); // weakly connected component group } + //Prints out the master traverser Invocation that'll call all other traversers //based on traverserID @@ -547,6 +360,7 @@ public class RuntimeConflictResolver { private void createMasterHashTableArray() { 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++) { @@ -579,7 +393,7 @@ public class RuntimeConflictResolver { for(int i=0;iclassID);\n break;"); cFile.println(" }"); @@ -631,19 +448,22 @@ public class RuntimeConflictResolver { cFile.println("\nint traverse(void * startingPtr, SESEcommon *record, int traverserID) {"); cFile.println(" switch(traverserID) {"); + /* + TODO WHAT IS THE RIGHT THING TO DO HERE?@!?!? for(Taint t: doneTaints.keySet()) { cFile.println(" case " + doneTaints.get(t)+ ":"); if(t.isRBlockTaint()) { cFile.println(" " + this.getTraverserInvocation(t.getVar(), "startingPtr, ("+t.getSESE().getSESErecordName()+" *)record", t.getSESE())); } else if (t.isStallSiteTaint()){ // JCJ either remove this or consider writing a comment explaining what it is commented out for - cFile.println("/* " + this.getTraverserInvocation(t.getVar(), "startingPtr, record", t.getStallSite())+"*/"); + cFile.println("// " + this.getTraverserInvocation(t.getVar(), "startingPtr, record", t.getStallSite())+""); } else { System.out.println("RuntimeConflictResolver encountered a taint that is neither SESE nor stallsite: " + t); } cFile.println(" break;"); } - + */ + cFile.println(" default:\n break;"); cFile.println(" }"); @@ -663,103 +483,141 @@ public class RuntimeConflictResolver { * signal a conflict within itself. */ - private void printCMethod(Hashtable created, Taint taint) { - String inVar = taint.getVar().getSafeSymbol(); - String rBlock; + private void printCMethod( FlatNode taskOrStallSite, + TempDescriptor var, + StateMachineForEffects smfe, + Integer weaklyConnectedComponent ) { + + // collect info for code gen + FlatSESEEnterNode task = null; + String inVar = var.getSafeSymbol(); + boolean isStallSite = !(taskOrStallSite instanceof FlatSESEEnterNode); + String rBlock; + SMFEState initialState = smfe.getInitialState(); + + if( isStallSite ) { + rBlock = taskOrStallSite.toString(); + } else { + task = (FlatSESEEnterNode) taskOrStallSite; + rBlock = task.getPrettyIdentifier(); + } + + String methodName = "void traverse___" + inVar + removeInvalidChars(rBlock) + "___(void * InVar, "; + int index = -1; + + if( isStallSite ) { + methodName += "SESEstall *record)"; + } else { + methodName += task.getSESErecordName() +" *record)"; + index = task.getInVarsForDynamicCoarseConflictResolution().indexOf( var ); + } - if(taint.isStallSiteTaint()) { - rBlock = taint.getStallSite().toString(); - } else if(taint.isRBlockTaint()) { - rBlock = taint.getSESE().getPrettyIdentifier(); + cFile .println( methodName + " {"); + headerFile.println( methodName + ";" ); + + cFile.println( " int totalcount = RUNBIAS;"); + if( isStallSite ) { + cFile.println(" record->rcrRecords[0].count = RUNBIAS;"); } else { - System.out.println("RCR CRITICAL ERROR: TAINT IS NEITHER A STALLSITE NOR SESE! " + taint.toString()); - return; + cFile.println(" record->rcrRecords["+index+"].count = RUNBIAS;"); } + + //clears queue and hashtable that keeps track of where we've been. + cFile.println(clearQueue + ";\n" + resetVisitedHashTable + ";"); + + cFile.println(" int traverserState = "+initialState.getID()+";"); + + //generic cast to ___Object___ to access ptr->allocsite field. + cFile.println(" RCRQueueEntry* entry = (struct ___Object___ *) InVar;"); + cFile.println(" struct ___Object___ * ptr = (struct ___Object___ *) InVar;"); + cFile.println(" if (InVar != NULL) {"); + cFile.println(" " + queryVistedHashtable + "(ptr);"); + cFile.println(" do {"); + + if( !isStallSite ) { + cFile.println(" if(unlikely(record->common.doneExecuting)) {"); + cFile.println(" record->common.rcrstatus=0;"); + cFile.println(" return;"); + cFile.println(" }"); + } + - //This hash table keeps track of all the case statements generated. - Hashtable cases = new Hashtable(); + // Traverse the StateMachineForEffects (a graph) + // that serves as a plan for building the heap examiner code. + // SWITCH on the states in the state machine, THEN + // SWITCH on the concrete object's allocation site THEN + // consider conflicts, enqueue more work, inline more SWITCHES, etc. + Set toVisit = new HashSet(); + Set visited = new HashSet(); - //Generate C cases - for (ConcreteRuntimeObjNode node : created.values()) { - printDebug(generalDebug, "Considering " + node.allocSite + " for traversal"); + toVisit.add( initialState ); + + cFile.println(" switch( traverserState ) {"); + + /* + + while( !toVisit.isEmpty() ) { + SMFEState state = toVisit.iterator().next(); + visited.add( state ); + toVisit.remove( state ); + + printDebug(generalDebug, "Considering " + state + " for traversal"); + if (!cases.containsKey(node.allocSite) && qualifiesForCaseStatement(node)) { printDebug(generalDebug, "+\t" + node.allocSite + " qualified for case statement"); addChecker(taint, node, cases, null, "ptr", 0); } + } - - String methodName; - int index=-1; - if (taint.isStallSiteTaint()) { - methodName= "void traverse___" + inVar + removeInvalidChars(rBlock) + "___(void * InVar, SESEstall *record)"; - } else { - methodName= "void traverse___" + inVar + removeInvalidChars(rBlock) + "___(void * InVar, "+taint.getSESE().getSESErecordName() +" *record)"; - FlatSESEEnterNode fsese=taint.getSESE(); - TempDescriptor tmp=taint.getVar(); - index=fsese.getInVarsForDynamicCoarseConflictResolution().indexOf(tmp); - } - cFile.println(methodName + " {"); - headerFile.println(methodName + ";"); - - if(cases.size() == 0) { - cFile.println(" return;"); - } else { - cFile.println(" int totalcount=RUNBIAS;"); - if (taint.isStallSiteTaint()) { - cFile.println(" record->rcrRecords[0].count=RUNBIAS;"); - } else { - cFile.println(" record->rcrRecords["+index+"].count=RUNBIAS;"); - } - - //clears queue and hashtable that keeps track of where we've been. - cFile.println(clearQueue + ";\n" + resetVisitedHashTable + ";"); - //generic cast to ___Object___ to access ptr->allocsite field. - cFile.println("struct ___Object___ * ptr = (struct ___Object___ *) InVar;\nif (InVar != NULL) {\n " + queryVistedHashtable + "(ptr);\n do {"); - if (taint.isRBlockTaint()) { - cFile.println(" if(unlikely(record->common.doneExecuting)) {"); - cFile.println(" record->common.rcrstatus=0;"); - cFile.println(" return;"); - cFile.println(" }"); - } - cFile.println(" switch(ptr->allocsite) {"); - - for(AllocSite singleCase: cases.keySet()) { - cFile.append(cases.get(singleCase)); - } + + + + + //This hash table keeps track of all the case statements generated. + Hashtable cases = new Hashtable(); - cFile.println(" default:\n break; "); - cFile.println(" }\n } while((ptr = " + dequeueFromQueueInC + ") != NULL);\n}"); + for(AllocSite singleCase: cases.keySet()) { + cFile.append(cases.get(singleCase)); + } - if (taint.isStallSiteTaint()) { - //need to add this - 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("}"); - } else { - 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(" default: break;"); + cFile.println(" } // end switch on traverser state"); + cFile.println(" } while((ptr = " + dequeueFromQueueInC + ") != NULL);"); + cFile.println(" } // end if inVar not null"); + */ + + + if( isStallSite ) { + 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(" }"); + } else { + 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("}"); cFile.flush(); } + /* * addChecker creates a case statement for every object that is an inset variable, has more * than 1 parent && has conflicts, or where resumes are possible * See .qualifiesForCaseStatement */ + /* private void addChecker(Taint taint, ConcreteRuntimeObjNode node, - Hashtable cases, + Hashtable cases, StringBuilder possibleContinuingCase, String prefix, int depth) { @@ -854,7 +712,7 @@ public class RuntimeConflictResolver { } private void printObjRefSwitchStatement(Taint taint, - Hashtable cases, + Hashtable cases, int pDepth, StringBuilder currCase, ArrayList refsAtParticularField, @@ -898,18 +756,6 @@ public class RuntimeConflictResolver { (node.hasPotentialToBeIncorrectDueToConflict) && node.descendantsObjConflict); } - // decide whether the given SESE doesn't have traversers at all - public boolean hasEmptyTraversers(FlatSESEEnterNode fsen) { - boolean hasEmpty = true; - - Set children = fsen.getChildren(); - for (Iterator iterator = children.iterator(); iterator.hasNext();) { - FlatSESEEnterNode child = (FlatSESEEnterNode) iterator.next(); - hasEmpty &= child.getInVarsForDynamicCoarseConflictResolution().size() == 0; - } - return hasEmpty; - - } //Note we assume instance of FlatSESEEnterNode to be sese blocks else they are considered stallsites. private Taint getProperTaintForEnterNode(FlatNode fn, VariableNode var) { FlatNode flatnode; @@ -927,12 +773,27 @@ 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 children = fsen.getChildren(); + for (Iterator iterator = children.iterator(); iterator.hasNext();) { + FlatSESEEnterNode child = (FlatSESEEnterNode) iterator.next(); + hasEmpty &= child.getInVarsForDynamicCoarseConflictResolution().size() == 0; + } + return hasEmpty; + + } private void printDebug(boolean guard, String debugStatements) { if(guard) System.out.println(debugStatements); } + /* //Walks the connected heaproot groups, coalesces them, and numbers them //Special Note: Lookup Table must already be created private void enumerateHeaproots() { @@ -973,176 +834,9 @@ public class RuntimeConflictResolver { System.out.println("=======================END LIST======================="); } } + */ - private void printoutTable(EffectsTable table) { - - System.out.println("==============EFFECTS TABLE PRINTOUT=============="); - for(Alloc as: table.table.keySet()) { - System.out.println("\tFor AllocSite " + as.getUniqueAllocSiteID()); - - BucketOfEffects boe = table.table.get(as); - - if(boe.potentiallyConflictingRoots != null && !boe.potentiallyConflictingRoots.isEmpty()) { - System.out.println("\t\tPotentially conflicting roots: "); - for(String key: boe.potentiallyConflictingRoots.keySet()) { - System.out.println("\t\t-Field: " + key); - System.out.println("\t\t\t" + boe.potentiallyConflictingRoots.get(key)); - } - } - for(Taint t: boe.taint2EffectsGroup.keySet()) { - System.out.println("\t\t For Taint " + t); - EffectsGroup eg = boe.taint2EffectsGroup.get(t); - - if(eg.hasPrimitiveConflicts()) { - System.out.print("\t\t\tPrimitive Conflicts at alloc " + as.getUniqueAllocSiteID() +" : "); - for(String field: eg.primitiveConflictingFields.keySet()) { - System.out.print(field + " "); - } - System.out.println(); - } - for(String fieldKey: eg.myObjEffects.keySet()) { - CombinedEffects ce = eg.myObjEffects.get(fieldKey); - System.out.println("\n\t\t\tFor allocSite " + as.getUniqueAllocSiteID() + " && field " + fieldKey); - System.out.println("\t\t\t\tread " + ce.hasReadEffect + "/"+ce.hasReadConflict + - " write " + ce.hasWriteEffect + "/" + ce.hasWriteConflict + - " SU " + ce.hasStrongUpdateEffect + "/" + ce.hasStrongUpdateConflict); - for(Effect ef: ce.originalEffects) { - System.out.println("\t" + ef); - } - } - } - } - - } - - private class EffectsGroup { - Hashtable myObjEffects; - //In the end, we don't really care what the primitive fields are. - Hashtable primitiveConflictingFields; - private boolean primConfRead; - private boolean primConfWrite; - - public EffectsGroup() { - myObjEffects = new Hashtable(); - primitiveConflictingFields = new Hashtable(); - - primConfRead = false; - primConfWrite = false; - } - - public void addPrimitive(Effect e, boolean conflict) { - CombinedEffects effects; - if((effects = primitiveConflictingFields.get(e.getField().getSymbol())) == null) { - effects = new CombinedEffects(); - primitiveConflictingFields.put(e.getField().getSymbol(), effects); - } - effects.add(e, conflict); - - primConfRead |= effects.hasReadConflict; - primConfWrite |= effects.hasWriteConflict; - } - - public void addObjEffect(Effect e, boolean conflict) { - CombinedEffects effects; - if((effects = myObjEffects.get(e.getField().getSymbol())) == null) { - effects = new CombinedEffects(); - myObjEffects.put(e.getField().getSymbol(), effects); - } - effects.add(e, conflict); - } - - public boolean isEmpty() { - return myObjEffects.isEmpty() && primitiveConflictingFields.isEmpty(); - } - - public boolean hasPrimitiveConflicts(){ - return !primitiveConflictingFields.isEmpty(); - } - - public CombinedEffects getPrimEffect(String field) { - return primitiveConflictingFields.get(field); - } - - public boolean hasObjectEffects() { - return !myObjEffects.isEmpty(); - } - - public CombinedEffects getObjEffect(String field) { - return myObjEffects.get(field); - } - } - - //Is the combined effects for all effects with the same affectedAllocSite and field - private class CombinedEffects { - ArrayList originalEffects; - - public boolean hasReadEffect; - public boolean hasWriteEffect; - public boolean hasStrongUpdateEffect; - - public boolean hasReadConflict; - public boolean hasWriteConflict; - public boolean hasStrongUpdateConflict; - - - public CombinedEffects() { - originalEffects = new ArrayList(); - - hasReadEffect = false; - hasWriteEffect = false; - hasStrongUpdateEffect = false; - - hasReadConflict = false; - hasWriteConflict = false; - hasStrongUpdateConflict = false; - } - - public boolean add(Effect e, boolean conflict) { - if(!originalEffects.add(e)) - return false; - - switch(e.getType()) { - case Effect.read: - hasReadEffect = true; - hasReadConflict = conflict; - break; - case Effect.write: - hasWriteEffect = true; - hasWriteConflict = conflict; - break; - case Effect.strongupdate: - hasStrongUpdateEffect = true; - hasStrongUpdateConflict = conflict; - break; - default: - System.out.println("RCR ERROR: An Effect Type never seen before has been encountered"); - assert false; - break; - } - return true; - } - - public boolean hasConflict() { - return hasReadConflict || hasWriteConflict || hasStrongUpdateConflict; - } - - public void mergeWith(CombinedEffects other) { - for(Effect e: other.originalEffects) { - if(!originalEffects.contains(e)){ - originalEffects.add(e); - } - } - - hasReadEffect |= other.hasReadEffect; - hasWriteEffect |= other.hasWriteEffect; - hasStrongUpdateEffect |= other.hasStrongUpdateEffect; - - hasReadConflict |= other.hasReadConflict; - hasWriteConflict |= other.hasWriteConflict; - hasStrongUpdateConflict |= other.hasStrongUpdateConflict; - } - } - + /* //This will keep track of a reference private class ObjRef { CombinedEffects myEffects; @@ -1349,7 +1043,9 @@ public class RuntimeConflictResolver { } } } - + */ + + /* private class WeaklyConectedHRGroup { HashSet connectedHRs; int id; @@ -1445,7 +1141,9 @@ public class RuntimeConflictResolver { this.nodesInHeap = nodesInHeap; } } - + */ + + /* private class TraversalInfo { public FlatNode f; public ReachGraph rg; @@ -1484,4 +1182,5 @@ public class RuntimeConflictResolver { return (f instanceof FlatSESEEnterNode); } } + */ } diff --git a/Robust/src/Runtime/oooJava/Queue_RCR.h b/Robust/src/Runtime/oooJava/Queue_RCR.h index a500cce8..38806463 100644 --- a/Robust/src/Runtime/oooJava/Queue_RCR.h +++ b/Robust/src/Runtime/oooJava/Queue_RCR.h @@ -11,6 +11,13 @@ struct RCRQueue { unsigned int tail; }; + +typedef struct RCRQueueEntry_t { + void* object; + int traverserState; +} RCRQueueEntry; + + int enqueueRCRQueue(void * ptr); void * dequeueRCRQueue(); void resetRCRQueue();