FlatSESEEnterNode.java CallGraph.java, RblockRelationAnalysis.java: maintains additional DS having a set of SESE that is the first reachable SESE from the current SESE through transitive method invocations
RuntimeConflictResolver.java : add helper function that checks if the given SESE only has empty traversers.
}
return callable;
}
+
+ // Returns a set of methods containing SESEs and located at the first
+ // in transitive call chain starting from d
+ public Set getFirstReachableMethodContainingSESE(Descriptor d,
+ Set<MethodDescriptor> methodsContainingSESEs) {
+ HashSet tovisit = new HashSet();
+ tovisit.add(d);
+ HashSet callable = new HashSet();
+ while (!tovisit.isEmpty()) {
+ Descriptor md = (Descriptor) tovisit.iterator().next();
+ tovisit.remove(md);
+ Set s = (Set) mapCaller2CalleeSet.get(md);
+ if (s != null) {
+ for (Iterator it = s.iterator(); it.hasNext();) {
+ MethodDescriptor md2 = (MethodDescriptor) it.next();
+ if (!callable.contains(md2)) {
+ callable.add(md2);
+ if (!methodsContainingSESEs.contains(md2)) {
+ // if current method has sese, do not need to go down
+ tovisit.add(md2);
+ }
+ }
+ }
+ }
+ }
+ callable.retainAll(methodsContainingSESEs);
+ return callable;
+ }
+
private void buildGraph() {
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
// to support calculation of leaf SESEs (no children even
// through method calls) for optimization during code gen
protected Set<MethodDescriptor> methodsContainingSESEs;
-
-
+
+ // maps method descriptor to SESE defined inside of it
+ // only contains top-level SESE definition in corresponding method
+ protected Hashtable<MethodDescriptor, Set<FlatSESEEnterNode>> md2seseSet;
+
public RBlockRelationAnalysis( State state,
TypeUtil typeUtil,
CallGraph callGraph ) {
fm2relmap =
new Hashtable< FlatMethod, Hashtable< FlatNode, Stack<FlatSESEEnterNode> > >();
+
+ md2seseSet = new Hashtable<MethodDescriptor, Set<FlatSESEEnterNode>>();
MethodDescriptor mdSourceEntry = typeUtil.getMain();
mainSESE.setfmEnclosing( fmMain );
mainSESE.setmdEnclosing( fmMain.getMethod() );
mainSESE.setcdEnclosing( fmMain.getMethod().getClassDesc() );
-
+
// add all methods transitively reachable from the
// source's main to set for analysis
Set<MethodDescriptor> descriptorsToAnalyze =
fsen.setfmEnclosing( fm );
fsen.setmdEnclosing( fm.getMethod() );
fsen.setcdEnclosing( fm.getMethod().getClassDesc() );
-
+
+ if(!fsen.getIsCallerSESEplaceholder() && fsen.getParent()==null ){
+ Set<FlatSESEEnterNode> seseSet=md2seseSet.get(fm.getMethod());
+ if(seseSet==null){
+ seseSet=new HashSet<FlatSESEEnterNode>();
+ }
+ seseSet.add(fsen);
+ md2seseSet.put(fm.getMethod(), seseSet);
+ }
+
if( seseStack.empty() ) {
rootSESEs.add( fsen );
fsen.setParent( null );
}
- protected boolean hasChildrenByCall( FlatSESEEnterNode fsen ) {
+ protected boolean hasChildrenByCall(FlatSESEEnterNode fsen) {
+
+ boolean hasChildrenByCall=false;
// visit every flat node in SESE body, find method calls that
// may transitively call methods with SESEs enclosed
Set<FlatNode> flatNodesToVisit = new HashSet<FlatNode>();
- flatNodesToVisit.add( fsen );
-
- Set<FlatNode> visited = new HashSet<FlatNode>();
+ flatNodesToVisit.add(fsen);
- while( !flatNodesToVisit.isEmpty() ) {
+ Set<FlatNode> visited = new HashSet<FlatNode>();
+
+ while (!flatNodesToVisit.isEmpty()) {
Iterator<FlatNode> fnItr = flatNodesToVisit.iterator();
FlatNode fn = fnItr.next();
- flatNodesToVisit.remove( fn );
- visited.add( fn );
+ flatNodesToVisit.remove(fn);
+ visited.add(fn);
- if( fn.kind() == FKind.FlatCall ) {
- FlatCall fc = (FlatCall) fn;
- MethodDescriptor mdCallee = fc.getMethod();
- Set reachable = new HashSet();
+ if (fn.kind() == FKind.FlatCall) {
+ FlatCall fc = (FlatCall) fn;
+ MethodDescriptor mdCallee = fc.getMethod();
+ Set reachable = new HashSet();
- reachable.add( mdCallee );
- reachable.addAll( callGraph.getAllMethods( mdCallee ) );
+ reachable.add(mdCallee);
+ reachable.addAll(callGraph.getAllMethods(mdCallee));
+
+ reachable.retainAll(methodsContainingSESEs);
+
+ if (!reachable.isEmpty()) {
+ hasChildrenByCall = true;
+
+ Set reachableSESEMethodSet =
+ callGraph.getFirstReachableMethodContainingSESE(mdCallee, methodsContainingSESEs);
+
+ if (methodsContainingSESEs.contains(mdCallee)) {
+ reachableSESEMethodSet.add(mdCallee);
+ }
+
+ for (Iterator iterator = reachableSESEMethodSet.iterator(); iterator.hasNext();) {
+ MethodDescriptor md = (MethodDescriptor) iterator.next();
+ Set<FlatSESEEnterNode> seseSet = md2seseSet.get(md);
+ if (seseSet != null) {
+ fsen.addSESEChildren(seseSet);
+ }
+ }
- reachable.retainAll( methodsContainingSESEs );
-
- if( !reachable.isEmpty() ) {
- return true;
}
}
- if( fn == fsen.getFlatExit() ) {
+ if (fn == fsen.getFlatExit()) {
// don't enqueue any futher nodes
continue;
}
-
- for( int i = 0; i < fn.numNext(); i++ ) {
- FlatNode nn = fn.getNext( i );
-
- if( !visited.contains( nn ) ) {
- flatNodesToVisit.add( nn );
- }
+
+ for (int i = 0; i < fn.numNext(); i++) {
+ FlatNode nn = fn.getNext(i);
+
+ if (!visited.contains(nn)) {
+ flatNodesToVisit.add(nn);
+ }
}
- }
+ }
- return false;
+ return hasChildrenByCall;
}
+
}
if( !fsen.getIsLeafSESE() ) {
output.println(" runningSESE->taskRecordMemPool = poolcreate( "+
maxTaskRecSizeStr+", freshTaskRecordInitializer );");
- if (state.RCR) {
- output.println(" createTR();");
- output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;");
+ if (state.RCR && !rcr.hasEmptyTraversers(fsen)) {
+ output.println(" createTR();");
+ output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;");
}
} else {
// make it clear we purposefully did not initialize this
+ generateTemp(fm, stalltd, null) + ";");
output.println(" stallrecord->common.classID=-"
+ rcr.getTraverserID(stalltd, fn) + ";");
-
+
output.println(" enqueueTR(TRqueue, (void *)stallrecord);");
if (state.COREPROF) {
////////////////
// count up memory conflict dependencies,
if(state.RCR) {
- dispatchMEMRC(fm, lb, fsen, output);
+ dispatchMEMRC(fm, lb, fsen, output);
} else if(state.OOOJAVA){
FlatSESEEnterNode parent = fsen.getParent();
Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent);
// Enqueue Task Record
if (state.RCR) {
- if( fsen != oooa.getMainSESE() ){
+ if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0){
output.println(" enqueueTR(TRqueue, (void *)seseToIssue);");
}
}
output.println("{");
output.println(" int idx,idx2;");
- //NEED TO FIX THIS
- //XXXXXXXXX
output.println(" struct rcrRecord *rec;");
- output.println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
+ output
+ .println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
- for(int i=0;i<inset.size();i++) {
- output.println(" rec=&" + paramsprefix + "->rcrRecords["+i+"];");
- output.println(" while(rec!=NULL) {");
- output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
+ for (int i = 0; i < inset.size(); i++) {
+ output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];");
+ output.println(" while(rec!=NULL) {");
+ output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
- int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i),fsen);
+ int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen);
- output.println(" rcr_RETIREHASHTABLE(hashstruct["+
- weaklyConnectedComponentIndex+
- "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
+ output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex
+ + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
- output.println(" }");// exit idx2 for loop
- output.println(" rec=rec->next;");
- output.println(" }");// exit rec while loop
+ output.println(" }");// exit idx2 for loop
+ output.println(" rec=rec->next;");
+ output.println(" }");// exit rec while loop
}
output.println("}");
}
// destroy this task's mempool if it is not a leaf task
if( !fsen.getIsLeafSESE() ) {
output.println(" pooldestroy( runningSESE->taskRecordMemPool );");
- if (state.RCR) {
+ if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) {
output.println(" returnTR();");
}
}
// records which is relevant to garbage collection
protected String firstDepRecField;
protected int numDepRecs;
-
+
+ // a set of sese located at the first in transitive call chain
+ // starting from the current sese
+ protected Set<FlatSESEEnterNode> seseChildren;
public FlatSESEEnterNode( SESENode sn ) {
this.id = identifier++;
staticInVars = new HashSet<TempDescriptor>();
dynamicInVars = new HashSet<TempDescriptor>();
dynamicVars = new HashSet<TempDescriptor>();
+ seseChildren = new HashSet<FlatSESEEnterNode>();
inVarsForDynamicCoarseConflictResolution = new Vector<TempDescriptor>();
return isCallerSESEplaceholder;
}
+ public void addSESEChildren(FlatSESEEnterNode child){
+ seseChildren.add(child);
+ }
+
+ public void addSESEChildren(Set<FlatSESEEnterNode> children){
+ seseChildren.addAll(children);
+ }
+
+ public Set<FlatSESEEnterNode> getSESEChildren(){
+ return seseChildren;
+ }
public boolean equals( Object o ) {
if( o == null ) {
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) {