import IR.TypeUtil;
import IR.MethodDescriptor;
import IR.Flat.*;
+import IR.ClassDescriptor;
public class LocalityAnalysis {
State state;
Hashtable<LocalityBinding, Hashtable<FlatNode,Hashtable<TempDescriptor, Integer>>> temptab;
Hashtable<LocalityBinding, Hashtable<FlatNode, Integer>> atomictab;
Hashtable<LocalityBinding, Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>> tempstosave;
+ Hashtable<ClassDescriptor, Set<LocalityBinding>> classtolb;
CallGraph callgraph;
TypeUtil typeutil;
this.lbtovisit=new Stack();
this.callgraph=callgraph;
this.tempstosave=new Hashtable<LocalityBinding, Hashtable<FlatAtomicEnterNode, Set<TempDescriptor>>>();
-
+ this.classtolb=new Hashtable<ClassDescriptor, Set<LocalityBinding>>();
doAnalysis();
}
+ /** This method returns a set of LocalityBindings for the parameter class. */
+
+ public Set<LocalityBinding> getClassBindings(ClassDescriptor cd) {
+ return classtolb.get(cd);
+ }
+
/** This method returns a set of LocalityBindings. A
* LocalityBinding specifies a context a method can be invoked in.
* It specifies whether the method is in a transaction and whether
lbmain.setGlobal(0, LOCAL);
lbtovisit.add(lbmain);
discovered.put(lbmain, lbmain);
-
+ if (!classtolb.containsKey(lbmain.getMethod().getClassDesc()))
+ classtolb.put(lbmain.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
+ classtolb.get(lbmain.getMethod().getClassDesc()).add(lbmain);
+
while(!lbtovisit.empty()) {
LocalityBinding lb=(LocalityBinding) lbtovisit.pop();
Integer returnglobal=lb.getGlobalReturn();
Integer currreturnval=EITHER; //Start off with the either value
for(Iterator methodit=methodset.iterator();methodit.hasNext();) {
MethodDescriptor md=(MethodDescriptor) methodit.next();
+ boolean isnative=md.getModifiers().isNative();
+
LocalityBinding lb=new LocalityBinding(md, isatomic);
+ if (isnative&&isatomic) {
+ System.out.println("Don't call native methods in atomic blocks!");
+ }
for(int i=0;i<fc.numArgs();i++) {
TempDescriptor arg=fc.getArg(i);
+ if(isnative&&(currtable.get(arg).equals(GLOBAL)||
+ currtable.get(arg).equals(CONFLICT)))
+ throw new Error("Potential call to native method "+md+" with global parameter:\n"+currlb.getExplanation());
lb.setGlobal(i,currtable.get(arg));
}
if (fc.getThis()!=null) {
throw new Error("Using type that can be either local or global in context:\n"+currlb.getExplanation());
if(thistype.equals(GLOBAL)&&!isatomic)
throw new Error("Using global object outside of transaction in context:\n"+currlb.getExplanation());
+ if (isnative&&thistype.equals(GLOBAL))
+ throw new Error("Potential call to native method "+md+" on global objects:\n"+currlb.getExplanation());
lb.setGlobalThis(thistype);
} else
lb.setGlobalThis(EITHER);//default value
+
//lb is built
if (!discovered.containsKey(lb)) {
- lb.setGlobalReturn(EITHER);
+ if (isnative)
+ lb.setGlobalReturn(LOCAL);
+ else
+ lb.setGlobalReturn(EITHER);
lb.setParent(currlb);
lbtovisit.add(lb);
discovered.put(lb, lb);
+ if (!classtolb.containsKey(lb.getMethod().getClassDesc()))
+ classtolb.put(lb.getMethod().getClassDesc(), new HashSet<LocalityBinding>());
+ classtolb.get(lb.getMethod().getClassDesc()).add(lb);
} else
lb=discovered.get(lb);
Integer returnval=lb.getGlobalReturn();
generateFlatMethod(fm, lb, outmethod);
}
}
-
-
} else {
Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
while(classit.hasNext()) {
if (state.TASK) {
outclassdefs.println(" int flag;");
outclassdefs.println(" void * flagptr;");
- if(state.OPTIONAL) outclassdefs.println(" int failedstatus;");
+ if(state.OPTIONAL)
+ outclassdefs.println(" int failedstatus;");
}
printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
printClassStruct(cn, classdefout);
classdefout.println("};\n");
- /* Cycle through methods */
- Iterator methodit=cn.getMethods();
- while(methodit.hasNext()) {
- /* Classify parameters */
- MethodDescriptor md=(MethodDescriptor)methodit.next();
- FlatMethod fm=state.getMethodFlat(md);
- generateTempStructs(fm, null);
-
- ParamsObject objectparams=(ParamsObject) paramstable.get(md);
- TempObject objecttemps=(TempObject) tempstable.get(md);
-
- /* Output parameter structure */
- if (GENERATEPRECISEGC) {
- output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
- output.println(" int size;");
- output.println(" void * next;");
- for(int i=0;i<objectparams.numPointers();i++) {
- TempDescriptor temp=objectparams.getPointer(i);
- output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
- }
- output.println("};\n");
+ if (state.DSM) {
+ /* Cycle through LocalityBindings */
+ for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cn).iterator();lbit.hasNext();) {
+ LocalityBinding lb=lbit.next();
+ MethodDescriptor md=lb.getMethod();
+ generateMethod(cn, md, lb, headersout, output);
}
+ } else {
+ /* Cycle through methods */
+ for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
+ /* Classify parameters */
+ MethodDescriptor md=(MethodDescriptor)methodit.next();
+ generateMethod(cn, md, null, headersout, output);
+ }
+ }
+ }
- /* Output temp structure */
- if (GENERATEPRECISEGC) {
- output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
- output.println(" int size;");
- output.println(" void * next;");
- for(int i=0;i<objecttemps.numPointers();i++) {
- TempDescriptor temp=objecttemps.getPointer(i);
- if (temp.getType().isNull())
- output.println(" void * "+temp.getSafeSymbol()+";");
- else
- output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
- }
- output.println("};\n");
+ private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
+ FlatMethod fm=state.getMethodFlat(md);
+ generateTempStructs(fm, null);
+
+ ParamsObject objectparams=(ParamsObject) paramstable.get(md);
+ TempObject objecttemps=(TempObject) tempstable.get(md);
+
+ /* Output parameter structure */
+ if (GENERATEPRECISEGC) {
+ output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
+ output.println(" int size;");
+ output.println(" void * next;");
+ for(int i=0;i<objectparams.numPointers();i++) {
+ TempDescriptor temp=objectparams.getPointer(i);
+ output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
}
-
- /* Output method declaration */
- if (md.getReturnType()!=null) {
- if (md.getReturnType().isClass()||md.getReturnType().isArray())
- headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
+ output.println("};\n");
+ }
+
+ /* Output temp structure */
+ if (GENERATEPRECISEGC) {
+ output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
+ output.println(" int size;");
+ output.println(" void * next;");
+ for(int i=0;i<objecttemps.numPointers();i++) {
+ TempDescriptor temp=objecttemps.getPointer(i);
+ if (temp.getType().isNull())
+ output.println(" void * "+temp.getSafeSymbol()+";");
else
- headersout.print(md.getReturnType().getSafeSymbol()+" ");
- } else
- //catch the constructor case
- headersout.print("void ");
- headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
-
- boolean printcomma=false;
- if (GENERATEPRECISEGC) {
- headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
- printcomma=true;
+ output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
}
+ output.println("};\n");
+ }
+
+ /********* Output method declaration ***********/
- //output parameter list
- for(int i=0;i<objectparams.numPrimitives();i++) {
- TempDescriptor temp=objectparams.getPrimitive(i);
- if (printcomma)
- headersout.print(", ");
- printcomma=true;
- if (temp.getType().isClass()||temp.getType().isArray())
- headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
- else
- headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
- }
- headersout.println(");\n");
- }
+ /* First the return type */
+ if (md.getReturnType()!=null) {
+ if (md.getReturnType().isClass()||md.getReturnType().isArray())
+ headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
+ else
+ headersout.print(md.getReturnType().getSafeSymbol()+" ");
+ } else
+ //catch the constructor case
+ headersout.print("void ");
+
+ /* Next the method name */
+ if (state.DSM) {
+ headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+ } else
+ headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+
+ boolean printcomma=false;
+ if (GENERATEPRECISEGC) {
+ headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
+ printcomma=true;
+ }
+
+ if (state.DSM&&lb.isAtomic()) {
+ if (printcomma)
+ headersout.print(", ");
+ headersout.print("transrecord_t * trans");
+ printcomma=true;
+ }
+
+ /* Output parameter list*/
+ for(int i=0;i<objectparams.numPrimitives();i++) {
+ TempDescriptor temp=objectparams.getPrimitive(i);
+ if (printcomma)
+ headersout.print(", ");
+ printcomma=true;
+ if (temp.getType().isClass()||temp.getType().isArray())
+ headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
+ else
+ headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
+ }
+ headersout.println(");\n");
}
ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
generateHeader(fm, lb, md!=null?md:task,output);
TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
+ if (state.DSM&&lb.getHasAtomic()) {
+ output.println("transrecord_t * trans;");
+ }
if (GENERATEPRECISEGC) {
if (md!=null)
} else
//catch the constructor case
output.print("void ");
- if (md!=null)
- output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
- else
+ if (md!=null) {
+ if (state.DSM) {
+ output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+ } else
+ output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+ } else
output.print(task.getSafeSymbol()+"(");
boolean printcomma=false;
printcomma=true;
}
+ if (state.DSM&&lb.isAtomic()) {
+ if (printcomma)
+ output.print(", ");
+ output.print("transrecord_t * trans");
+ printcomma=true;
+ }
+
if (md!=null) {
/* Method */
for(int i=0;i<objectparams.numPrimitives();i++) {
//GENERATE HEADERS
headers.println("#include \"task.h\"\n\n");
-
//STRUCT PREDICATEMEMBER
headers.println("struct predicatemember{");